--- title: SEO and Meta description: Improve your Nuxt app's SEO with powerful head config, composables and components. navigation.icon: i-ph-file-search-duotone --- ## Defaults Out-of-the-box, Nuxt provides sane defaults, which you can override if needed. ```ts twoslash [nuxt.config.ts] export default defineNuxtConfig({ app: { head: { charset: 'utf-8', viewport: 'width=device-width, initial-scale=1', } } }) ``` Providing an [`app.head`](/docs/api/nuxt-config#head) property in your [`nuxt.config.ts`](/docs/guide/directory-structure/nuxt-config) allows you to customize the head for your entire app. ::callout This method does not allow you to provide reactive data. We recommend to use `useHead()` in `app.vue`. :: Shortcuts are available to make configuration easier: `charset` and `viewport`. You can also provide any of the keys listed below in [Types](#types). ## `useHead` The [`useHead`](/docs/api/composables/use-head) composable function allows you to manage your head tags in a programmatic and reactive way, powered by [Unhead](https://unhead.unjs.io). As with all composables, it can only be used with a components `setup` and lifecycle hooks. ```vue twoslash [app.vue] ``` We recommend to take a look at the [`useHead`](/docs/api/composables/use-head) and [`useHeadSafe`](/docs/api/composables/use-head-safe) composables. ## `useSeoMeta` The [`useSeoMeta`](/docs/api/composables/use-seo-meta) composable lets you define your site's SEO meta tags as a flat object with full TypeScript support. This helps you avoid typos and common mistakes, such as using `name` instead of `property`. ```vue twoslash [app.vue] ``` :read-more{to="/docs/api/composables/use-seo-meta"} ## Components Nuxt provides ``, `<Base>`, `<NoScript>`, `<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. <!-- @case-police-ignore html --> ```vue [app.vue] <script setup lang="ts"> const title = ref('Hello World') </script> <template> <div> <Head> <Title>{{ title }}

{{ title }}

``` ## Types Below are the non-reactive types used for [`useHead`](/docs/api/composables/use-head), [`app.head`](/docs/api/nuxt-config#head) and components. ```ts interface MetaObject { title?: string titleTemplate?: string | ((title?: string) => string) templateParams?: Record> base?: Base link?: Link[] meta?: Meta[] style?: Style[] script?: Script[] noscript?: Noscript[]; htmlAttrs?: HtmlAttributes; bodyAttrs?: BodyAttributes; } ``` See [@unhead/schema](https://github.com/unjs/unhead/blob/main/packages/schema/src/schema.ts) for more detailed types. ## Features ### Reactivity Reactivity is supported on all properties, as computed, getters and reactive. It's recommended to use getters (`() => value`) over computed (`computed(() => value)`). ::code-group ```vue twoslash [useHead] ``` ```vue twoslash [useSeoMeta] ``` ```vue [Components] ``` :: ### Title Template You can use the `titleTemplate` option to provide a dynamic template for customizing the title of your site. for example, by adding the name of your site to the title of every page. The `titleTemplate` can either be a string, where `%s` is replaced with the title, or a function. If you want to use a function (for full control), then this cannot be set in your `nuxt.config`, and it is recommended instead to set it within your `app.vue` file, where it will apply to all pages on your site: ::code-group ```vue twoslash [useHead] ``` :: Now, if you set the title to `My Page` with [`useHead`](/docs/api/composables/use-head) on another page of your site, the title would appear as 'My Page - Site Title' in the browser tab. You could also pass `null` to default to 'Site Title'. ### Body Tags You can use the `tagPosition: 'bodyClose'` option on applicable tags to append them to the end of the `` tag. For example: ```vue twoslash ``` ## Examples ### With `definePageMeta` Within your [`pages/` directory](/docs/guide/directory-structure/pages), you can use `definePageMeta` along with [`useHead`](/docs/api/composables/use-head) 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): ```vue twoslash [pages/some-page.vue] ``` And then in your layout file, you might use the route's metadata you have previously set: ```vue twoslash [layouts/default.vue] ``` :link-example{to="/docs/examples/features/meta-tags"} :read-more{to="/docs/guide/directory-structure/pages/#page-metadata"} ### Dynamic Title In the example below, `titleTemplate` is set either as a string with the `%s` placeholder or as a `function`, which allows greater flexibility in setting the page title dynamically for each route of your Nuxt app: ```vue twoslash [app.vue] ``` ```vue twoslash [app.vue] ``` `nuxt.config` is also used as an alternative way of setting the page title. However, `nuxt.config` does not allow the page title to be dynamic. Therefore, it is recommended to use `titleTemplate` in the `app.vue` file to add a dynamic title, which is then applied to all routes of your Nuxt app. ### External CSS The example below shows how you might enable Google Fonts using either the `link` property of the [`useHead`](/docs/api/composables/use-head) composable or using the `` component: ::code-group ```vue twoslash [useHead] ``` ```vue [Components] ``` ::