Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/dvlkit/nuxe/llms.txt

Use this file to discover all available pages before exploring further.

Nuxe re-exports useHead, useHeadSafe, and useSeoMeta directly from @unhead/vue. Tags declared with any of these composables are injected into the HTML <head> during server-side rendering and updated reactively on every client-side navigation — no lifecycle hacks, document.title assignments, or cleanup code required.
useHead, useHeadSafe, and useSeoMeta are auto-imported in every page and component. You do not need to add an explicit import statement unless you prefer to be explicit.

useHead(input)

Use useHead to set the page title, meta tags, link tags, scripts, or any other element that belongs in <head>. The real about.vue page in the Nuxe playground demonstrates the pattern:
<!-- app/pages/about.vue -->
<script setup lang="ts">
useHead({
  title: 'About — nuxe',
  meta: [
    { name: 'description', content: 'Página about de nuxe' }
  ]
})
</script>

<template>
  <h1>About page</h1>
</template>
The full set of accepted keys mirrors the @unhead/vue UseHeadInput type:
KeyTypeDescription
titlestring | () => stringDocument title
metaMetaTag[]<meta> elements
linkLinkTag[]<link> elements (stylesheets, canonical, etc.)
scriptScriptTag[]<script> elements
styleStyleTag[]Inline <style> elements
htmlAttrsobjectAttributes added to <html>
bodyAttrsobjectAttributes added to <body>

useHeadSafe(input)

useHeadSafe has the same signature as useHead but sanitises every string value before inserting it into the DOM. Use it whenever any part of the head input originates from user-provided data to prevent XSS:
<script setup lang="ts">
const props = defineProps<{ productName: string }>()

// Safe even if productName contains HTML characters
useHeadSafe({
  title: props.productName,
  meta: [
    { name: 'description', content: props.productName }
  ]
})
</script>

useSeoMeta(input)

useSeoMeta is a typed, SEO-focused shorthand. Instead of spelling out individual <meta> elements you describe your intent with named keys and the composable generates the correct tags — including Open Graph and Twitter Card variants:
<script setup lang="ts">
useSeoMeta({
  title: 'My Page',
  description: 'My page description',
  ogTitle: 'My Page',
  ogDescription: 'My page description',
  ogImage: 'https://example.com/og.png',
  twitterCard: 'summary_large_image',
})
</script>
useSeoMeta prevents common mistakes such as accidentally setting og:description via a raw <meta property="…"> with the wrong attribute name.

Reactive titles

Pass a function (or a computed ref) instead of a static string to make any head value update automatically when reactive data changes:
<script setup lang="ts">
const route = useRoute()

useHead({
  title: () => `${route.meta.title} — My App`
})
</script>
You can also drive the title from async data:
<script setup lang="ts">
const { data: product } = await useFetch('/api/product/1')

useHead({
  title: () => product.value?.name ?? 'Loading…'
})
</script>
The title string is recomputed on every render cycle on the client, so it stays in sync without any manual watchers.

Combining composables

You can call useHead and useSeoMeta together in the same component — their outputs are merged:
<script setup lang="ts">
useHead({
  link: [{ rel: 'canonical', href: 'https://example.com/page' }]
})

useSeoMeta({
  title: 'My Page',
  description: 'A great page.',
  ogImage: 'https://example.com/og.png',
})
</script>

SSR behaviour

During server-side rendering, Nuxe serialises all head tags collected by useHead / useSeoMeta and writes them directly into the <head> of the initial HTML response. On the client, @unhead/vue hydrates from that rendered state and takes over reactivity — there is no double-rendering or flash of missing meta tags. The app/error.vue page uses exactly the same pattern to set a dynamic title that reflects the current error:
<script setup lang="ts">
import { useHead } from '@dvlkit/nuxe'
import type { NuxeError } from '@dvlkit/nuxe'

const props = defineProps<{ error: NuxeError }>()

useHead({
  title: `${props.error.statusCode}${props.error.statusMessage}`,
})
</script>

Build docs developers (and LLMs) love