<head> element
The
<head>-element
is a crucial element in HTML to set metadata for a page. It allows you to:
- Set the document title with
<title> - Specify page metadata with
<meta> - Link to resources like stylesheets with
<link> - Include JavaScript code with
<script>
InfoThe outer HTML structure including
<head>is typically created inside_app.tsx.
Passing metadata from ctx.state
For simple scenarios passing metadata along from a handler or a
middleware by writing to ctx.state is often
sufficient.
import { define } from "../util.ts";
export default define.page((ctx) => {
return (
<html lang="en">
<head>
<meta charset="utf-8" />
<title>{ctx.state.title ?? "Welcome!"}</title>
</head>
<body>
<ctx.Component />
</body>
</html>
);
});Using the <Head>-component
For more complex scenarios, or to set page metadata from
islands, Fresh ships with the <Head>-component.
import { Head } from "fresh/runtime";
export default define.page((ctx) => {
return (
<div>
<Head>
<title>About me</title>
</Head>
<h1>About me</h1>
<p>I like Fresh!</p>
</div>
);
});Dynamic head updates from islands
The <Head> component works in islands too. When
component state changes, the document head is updated automatically:
import { useState } from "preact/hooks";
import { Head } from "fresh/runtime";
export default function MetaUpdater() {
const [title, setTitle] = useState("Welcome");
return (
<div>
<Head>
<title>{title}</title>
</Head>
<button onClick={() => setTitle("Updated!")}>Change title</button>
</div>
);
}Avoiding duplicate tags
You might end up with duplicate tags, when multiple <Head /> components are
rendered on the same page. Fresh will employ the following strategies to find
the matching element:
- For
<title>elements Fresh will setdocument.titledirectly - Check if an element with the same
keyexists - Check if an element with the same
idattribute - Only for
<meta>elements: Check if there is a<meta>element with the samenameattribute - Only for
<link>elements: Check if there is a<link>element with the samerelattribute - No matching element was found, Fresh will create a new one and append it to
<head>
When multiple <Head> components render an element with the same key, the
last one rendered wins. Since Fresh renders top-down (app wrapper -> layout
-> route -> page component), a route page can override defaults set in
_app.tsx by using the same key prop.
InfoThe
<title>-tag is automatically deduplicated, even without akeyprop.