nuxt logo

文档翻译(非官方)

SEO和元数据

利用强大的头部设置、composables 和组件来改善 Nuxt 应用的 SEO。

Nuxt 的头部标签管理由 Unhead 实现。它默认提供适当的设置,并提供一些强大的 composables 和大量选项来管理应用的头部和 SEO 元标签。

Nuxt 设置

您可以通过在 nuxt.config.ts 中设置 app.head 属性来静态地自定义整个应用的头部。

这种方法无法提供响应式数据。我们建议在 app.vue 中使用 useHead()

在此设置网站的默认标题、语言和图标等不变的标签是一个良好的实践。

nuxt.config.ts
export default defineNuxtConfig({
  app: {
    head: {
      title: 'Nuxt', // 默认回退标题
      htmlAttrs: {
        lang: 'en',
      },
      link: [
        { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' },
      ]
    }
  }
})

您还可以选择性地提供以下 Types 中列出的键。

默认标签

Nuxt 默认提供以下标签,这确保您的网站从一开始就能正常运行。

  • viewport: width=device-width, initial-scale=1
  • charset: utf-8

通常不需要覆盖这些默认设置,但可以使用带键的快捷方式进行更新。

nuxt.config.ts
export default defineNuxtConfig({
  app: {
    head: {
      // 更新 Nuxt 默认设置
      charset: 'utf-16',
      viewport: 'width=device-width, initial-scale=1, maximum-scale=1',
    }
  }
})

useHead

useHead composable 函数支持响应式输入,并可以以编程方式管理头部标签。

app.vue
useHead({
  title: 'My App',
  meta: [
    { name: 'description', content: 'My amazing site.' }
  ],
  bodyAttrs: {
    class: 'test'
  },
  script: [ { innerHTML: 'console.log(\'Hello world\')' } ]
})

我们建议查看 useHeaduseHeadSafe composables。

useSeoMeta

useSeoMeta composable 允许您以完全类型安全的对象定义网站的 SEO 元标签。

这有助于避免拼写错误和常见错误,例如使用 name 而不是 property

app.vue
useSeoMeta({
  title: 'My Amazing Site',
  ogTitle: 'My Amazing Site',
  description: 'This is my amazing site, let me tell you all about it.',
  ogDescription: 'This is my amazing site, let me tell you all about it.',
  ogImage: 'https://example.com/image.png',
  twitterCard: 'summary_large_image',
})
另请参阅 api > composables > use-seo-meta

组件

虽然在所有情况下都推荐使用 useHead,但在模板中使用组件定义头部标签在某些情况下可能特别有用。

为此,Nuxt 提供了以下组件:<Title><Base><NoScript><Style><Meta><Link><Body><Html>。请注意这些组件的大小写,这确保不会使用无效的原生 HTML 标签。

<Head><Body> 可以接受嵌套的元标签(为了美观),但这不会影响它们在最终 HTML 中的渲染位置。

app.vue
<script setup lang="ts">
const title = ref('Hello World')
</script>

<template>
  <div>
    <Head>
      <Title>{{ title }}</Title>
      <Meta name="description" :content="title" />
      <Style>
      body { background-color: green; }
      </Style>
    </Head>

    <h1>{{ title }}</h1>
  </div>
</template>

建议将您的组件包装在 <Head><Html> 组件中。标签将被直观地移除。

类型

以下是 useHeadapp.head 和组件的非响应式类型。

interface MetaObject {
  title?: string
  titleTemplate?: string | ((title?: string) => string)
  templateParams?: Record<string, string | Record<string, string>>
  base?: Base
  link?: Link[]
  meta?: Meta[]
  style?: Style[]
  script?: Script[]
  noscript?: Noscript[];
  htmlAttrs?: HtmlAttributes;
  bodyAttrs?: BodyAttributes;
}

有关详细类型,请参阅 @unhead/vue

功能

响应性

所有属性都支持响应性。通过提供计算值、getter 或响应式对象来实现这一点。

const description = ref('My amazing site.')

useHead({
  meta: [
    { name: 'description', content: description }
  ],
})

标题模板

您可以使用 titleTemplate 选项提供一个动态模板来自定义网站的标题。例如,可以在所有页面的标题中添加网站名称。

titleTemplate 可以是一个字符串,其中 %s 被替换为标题,或者是一个函数。

如果希望使用函数(以获得完全控制),则不能在 nuxt.config 中设置。相反,建议在 app.vue 文件中设置,以便在所有页面中使用。

useHead({
  titleTemplate: (titleChunk) => {
    return titleChunk ? `${titleChunk} - Site Title` : 'Site Title';
  }
})

现在,如果您在网站的其他页面中使用 useHead 将标题设置为 My Page,浏览器标签中将显示 'My Page - Site Title'。您也可以传递 null 以将默认值设置为 'Site Title'。

模板参数

除了默认的 %s,您还可以使用 templateParamstitleTemplate 提供额外的占位符。这允许更动态的标题生成。

useHead({
  titleTemplate: (titleChunk) => {
    return titleChunk ? `${titleChunk} %separator %siteName` : '%siteName';
  },
  templateParams: {
    siteName: 'Site Title',
    separator: '-'
  }
})

Body 标签

可以使用 tagPosition: 'bodyClose' 选项将适用的标签添加到 <body> 标签的末尾。

例如:

useHead({
  script: [
    {
      src: 'https://third-party-script.com',
      // 有效选项为:'head' | 'bodyClose' | 'bodyOpen'
      tagPosition: 'bodyClose'
    }
  ]
})

示例

使用 definePageMeta

pages/ 目录中,可以使用 definePageMetauseHead 一起设置基于当前路由的元数据。

例如,首先可以设置当前页面的标题(由于在构建时通过宏提取,因此无法动态设置):

pages/some-page.vue
definePageMeta({
  title: 'Some Page'
})

然后,在布局文件中,可以使用先前设置的路由元数据:

layouts/default.vue
const route = useRoute()

useHead({
  meta: [{ property: 'og:title', content: `App Name - ${route.meta.title}` }]
})
示例代码的编辑与预览examples > features > meta-tags
另请参阅 guide > directory-structure > pages > #page-metadata

动态标题

在以下示例中,titleTemplate 被设置为包含 %s 占位符的字符串或 function。这使得可以为 Nuxt 应用的每个路由动态设置页面标题:

app.vue
useHead({
  // 作为字符串,
  // 其中 `%s` 被替换为标题
  titleTemplate: '%s - Site Title',
})
app.vue
useHead({
  // 或作为函数
  titleTemplate: (productCategory) => {
    return productCategory
      ? `${productCategory} - Site Title`
      : 'Site Title'
  }
})

页面标题的设置也可以在 nuxt.config 中使用。然而,在 nuxt.config 中无法动态设置页面标题。因此,建议在 app.vue 文件中使用 titleTemplate 添加动态标题,并将其应用于 Nuxt 应用的所有路由。

外部 CSS

以下示例展示了如何使用 useHead composable 的 link 属性或 <Link> 组件启用 Google Fonts。

useHead({
  link: [
    {
      rel: 'preconnect',
      href: 'https://fonts.googleapis.com'
    },
    {
      rel: 'stylesheet',
      href: 'https://fonts.googleapis.com/css2?family=Roboto&display=swap',
      crossorigin: ''
    }
  ]
})