Head Management

Out-of-the-box, Nuxt provides good default values for charset and viewport meta tags, but you can override these if you need to, as well as customize other meta tags for your site in several different ways.

👉

Read more in API > Configuration > Nuxt Config #head.

useHead Composable

Within your setup function, you can call useHead with an object of meta properties with keys corresponding to meta tags: title, titleTemplate, base, script, style, meta and link, as well as htmlAttrs and bodyAttrs. There are also two shorthand properties, charset and viewport, which set the corresponding meta tags. Alternatively, you can pass a function returning the object for reactive metadata.

For example:

  1. <script setup>
  2. useHead({
  3. titleTemplate: 'My App - %s', // or, title => `My App - ${title}`
  4. viewport: 'width=device-width, initial-scale=1, maximum-scale=1',
  5. charset: 'utf-8',
  6. meta: [
  7. { name: 'description', content: 'My amazing site.' }
  8. ],
  9. bodyAttrs: {
  10. class: 'test'
  11. }
  12. })
  13. </script>

👉

Read more in API > Composables > Use Head.

Meta Components

Nuxt provides <Title>, <Base>, <Script>, <Style>, <Meta>, <Link>, <Body>, <Html> and <Head> components so that you can interact directly with your metadata within your component’s template.

Because these component names match native HTML elements, it is very important that they are capitalized in the template.

<Head> and <Body> can accept nested meta tags (for aesthetic reasons) but this has no effect on where the nested meta tags are rendered in the final HTML.

For example:

app.vue

  1. <template>
  2. <div>
  3. Hello World
  4. <Html :lang="dynamic > 50 ? 'en-GB' : 'en-US'">
  5. <Head>
  6. <Title>{{ dynamic }} title</Title>
  7. <Meta name="description" :content="`My page's ${dynamic} description`" />
  8. <Link rel="preload" href="/test.txt" as="script" />
  9. <Style type="text/css" :children="styleString" />
  10. </Head>
  11. </Html>
  12. <button class="blue" @click="dynamic = Math.random() * 100">
  13. Click me
  14. </button>
  15. </div>
  16. </template>
  17. <script>
  18. export default {
  19. data: () => ({ dynamic: 49, styleString: 'body { background-color: green; }' })
  20. }
  21. </script>

Example: usage with definePageMeta

You can use definePageMeta along with useHead to set metadata based on the current route.

For example, you can first set the current page title (this is extracted at build time via a macro, so it can’t be set dynamically):

pages/some-page.vue

  1. <script setup>
  2. definePageMeta({
  3. title: 'Some Page'
  4. })
  5. </script>

And then in your layout file, you might use the route’s metadata you have previously set:

layouts/default.vue

  1. <script setup>
  2. const route = useRoute()
  3. useHead({
  4. meta: [{ name: 'og:title', content: `App Name - ${route.meta.title}` }]
  5. })
  6. </script>

🔎

Read and edit a live example in Examples > Composables > Use Head