Fresh logo

Modifying the <head>

We can use the <Head /> component in $fresh/runtime.ts to add elements as children of the <head> element. By adding elements as children of Fresh’s <Head /> tag, these automatically get injected into the <head> element of the web page. Some uses include:

  • Setting the document title using <title>
  • Specifying page metadata using <meta>
  • Linking to resources like stylesheets using <link>
  • Including third-party JavaScript code using <script>
routes/index.tsx
import { Head } from "$fresh/runtime.ts";

export default function Home() {
  return (
    <>
      <Head>
        <meta charset="UTF-8" />
        <title>Fresh App</title>
        <meta
          name="description"
          content="This is a brief description of Fresh"
        />
        <link rel="stylesheet" href="styles.css" />
        <script src="script.js"></script>
      </Head>
      <div class="p-4 mx-auto max-w-screen-md">
        <h1>Hello World</h1>
      </div>
    </>
  );
}

Avoiding duplicate tags

You might end up with duplicate tags, when multiple <Head /> components are rendered on the same page. This can happen when you render <Head /> in a route and another <Head /> in another component for example.

// routes/page-a.tsx
<Head>
  <meta name="og:title" content="This is a title" />
</Head>

// components/MyTitle.tsx
<Head>
  <meta name="og:title" content="Other title" />
</Head>

To ensure that the tag is not duplicated, Fresh supports setting the key prop. By giving matching elements the same key prop, only the last one will be rendered.

  // routes/page-a.tsx
  <Head>
-   <meta name="og:title" content="This is a title" />
+   <meta name="og:title" content="This is a title" key="title" />
  </Head>

  // components/MyTitle.tsx
  <Head>
-   <meta name="og:title" content="Other title" />
+   <meta name="og:title" content="Other title" key="title" />
  </Head>

The rendered page will only include the <meta>-tag with "Other title".

[info]: The ``-tag is automatically deduplicated, even without a `key` prop.</blockquote> </div><div class="mb-8"><div class="px-4 md:px-0 mt-8 flex flex-col sm:flex-row gap-4 justify-between"><a href="/docs/examples/migrating-to-tailwind" class="px-4 py-2 text-left rounded border border-gray-200 grid border-solid w-full hover:border-green-600 transition-colors"><span class="text-sm text-gray-600">Previous page</span><span class="text-green-600 font-medium">Migrating to Tailwind</span></a><a href="/docs/examples/writing-tests" class="px-4 py-2 text-right rounded border border-gray-200 border-solid grid w-full hover:border-green-600 transition-colors"><span class="text-sm text-gray-600">Next page</span><span class="text-green-600 font-medium">Writing tests</span></a></div></div><hr><div class="px-4 md:px-0 flex justify-between my-6"><a href="https://github.com/denoland/fresh/edit/main/docs/latest/examples/modifying-the-head.md" class="text-green-600 underline flex items-center" target="_blank" rel="noopener noreferrer"><svg class="w-4 h-4 inline-block mr-1"><use href="/icons.svg#external"></use></svg>Edit this page on GitHub</a></div></div></div><div class="xl:ml-[3.75rem]"><footer class="border-t-2 border-gray-200 md:h-16 flex mt-16 justify-center md:mx-16 undefined"><div class="flex flex-col sm:flex-row gap-4 justify-between items-center max-w-screen-xl mx-auto w-full sm:px-6 md:px-8 p-4"><div class="text-gray-600 text-center"><span>© 2024 the Fresh authors</span></div><div class="flex items-center gap-8"><a href="https://github.com/denoland/fresh" class="text-gray-600 hover:underline">Source</a><a href="https://github.com/denoland/fresh/blob/main/LICENSE" class="text-gray-600 hover:underline">License</a><a href="https://github.com/denoland/fresh/blob/main/CODE_OF_CONDUCT.md" class="text-gray-600 hover:underline">Code of Conduct</a></div></div></footer></div></main></div><!--/frsh:partial--></div></div><script type="module" nonce="0cb3f00f8bf343f9aec3ceb28a7dae97">import { boot } from "/fresh-runtime.js?__frsh_c=311bfe9e5322fe77f7e63aadf8a209e1d5a9c0ab";import SearchButton from "/SearchButton.js?__frsh_c=311bfe9e5322fe77f7e63aadf8a209e1d5a9c0ab";import VersionSelect from "/VersionSelect.js?__frsh_c=311bfe9e5322fe77f7e63aadf8a209e1d5a9c0ab";import { TableOfContents } from "/TableOfContents.js?__frsh_c=311bfe9e5322fe77f7e63aadf8a209e1d5a9c0ab";boot({SearchButton,VersionSelect,TableOfContents},"[[1,5,16,19,22],{\"slots\":2,\"props\":3},[],{\"class\":4},\"mr-4 sm:mr-0\",{\"slots\":6,\"props\":7},[],{\"selectedVersion\":8,\"versions\":9},\"latest\",[10,13],{\"label\":11,\"value\":11,\"href\":12},\"canary\",\"/docs/canary/examples/modifying-the-head\",{\"label\":14,\"value\":8,\"href\":15},\"1.6.8\",\"/docs/examples/modifying-the-head\",{\"slots\":17,\"props\":18},[],{\"class\":4},{\"slots\":20,\"props\":21},[],{\"selectedVersion\":8,\"versions\":9},{\"slots\":23,\"props\":24},[],{\"headings\":25},[26],{\"id\":27,\"html\":28},\"-avoiding-duplicate-tags\",\"Avoiding duplicate tags\"]");</script></body></html>