SEO 和 Meta
Nuxt head 标签管理由 Unhead 提供支持。它提供合理的默认值、多个强大的可组合项以及众多配置选项,用于管理应用的 head 和 SEO 元标签。
¥Nuxt head tag management is powered by Unhead. It provides sensible defaults, several powerful composables and numerous configuration options to manage your app's head and SEO meta tags.
Nuxt 配置
¥Nuxt Config
在 nuxt.config.ts
中提供 app.head
属性,可以静态自定义整个应用的 head 部分。
¥Providing an app.head
property in your nuxt.config.ts
allows you to statically customize the head for your entire app.
app.vue
中使用 useHead()
。最好在此处设置不会更改的标签,例如网站默认标题、语言和网站图标。
¥It's good practice to set tags here that won't change such as your site title default, language and favicon.
export default defineNuxtConfig({
app: {
head: {
title: 'Nuxt', // default fallback title
htmlAttrs: {
lang: 'en',
},
link: [
{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' },
]
}
}
})
你还可以提供 类型 中列出的任何键。
¥You can also provide any of the keys listed below in Types.
默认标签
¥Defaults Tags
Nuxt 默认提供某些标签,以确保你的网站开箱即用。
¥Some tags are provided by Nuxt by default to ensure your website works well out of the box.
viewport
:width=device-width, initial-scale=1
charset
:utf-8
虽然大多数网站不需要覆盖这些默认设置,但你可以使用快捷键进行更新。
¥While most sites won't need to override these defaults, you can update them using the keyed shortcuts.
export default defineNuxtConfig({
app: {
head: {
// update Nuxt defaults
charset: 'utf-16',
viewport: 'width=device-width, initial-scale=1, maximum-scale=1',
}
}
})
useHead
useHead
可组合函数支持响应式输入,允许你以编程式方式管理 head 标签。
¥The useHead
composable function supports reactive input, allowing you to manage your head tags programmatically.
<script setup lang="ts">
useHead({
title: 'My App',
meta: [
{ name: 'description', content: 'My amazing site.' }
],
bodyAttrs: {
class: 'test'
},
script: [ { innerHTML: 'console.log(\'Hello world\')' } ]
})
</script>
我们建议查看 useHead
和 useHeadSafe
可组合项。
¥We recommend to take a look at the useHead
and useHeadSafe
composables.
useSeoMeta
useSeoMeta
可组合项允许你将网站的 SEO 元标记定义为具有完全类型安全的对象。
¥The useSeoMeta
composable lets you define your site's SEO meta tags as an object with full type safety.
这有助于你避免拼写错误和常见错误,例如将 property
写成 name
。
¥This helps you avoid typos and common mistakes, such as using name
instead of property
.
<script setup lang="ts">
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',
})
</script>
组件
¥Components
虽然建议在所有情况下都使用 useHead
,但你可能更喜欢使用组件在模板中定义 head 标签。
¥While using useHead
is recommended in all cases, you may have a personal preference for defining your head tags in your template using components.
Nuxt 为此提供了以下组件:<Title>
、<Base>
、<NoScript>
、<Style>
、<Meta>
、<Link>
、<Body>
、<Html>
和 <Head>
。请注意这些组件的首字母大写,以确保我们不会使用无效的原生 HTML 标签。
¥Nuxt provides the following components for this purpose: <Title>
, <Base>
, <NoScript>
, <Style>
, <Meta>
, <Link>
, <Body>
, <Html>
and <Head>
. Note
the capitalization of these components ensuring we don't use invalid native HTML tags.
<Head>
和 <Body>
可以接受嵌套的元标记(出于美观原因),但这不会影响嵌套元标记在最终 HTML 中的渲染位置。
¥<Head>
and <Body>
can accept nested meta tags (for aesthetic reasons) but this does not affect where the nested meta tags are rendered in the final HTML.
<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>
组件中,因为这样可以更直观地删除标签。
¥It's suggested to wrap your components in either a <Head>
or <Html>
components as tags will be deduped more intuitively.
类型
¥Types
以下是用于 useHead
、app.head
和组件的非反应式类型。
¥Below are the non-reactive types used for useHead
, app.head
and components.
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。
¥See @unhead/vue for more detailed types.
功能
¥Features
响应式
¥Reactivity
所有属性都支持响应式,可以通过提供计算值、getter 或响应式对象来实现。
¥Reactivity is supported on all properties, by providing a computed value, a getter, or a reactive object.
<script setup lang="ts">
const description = ref('My amazing site.')
useHead({
meta: [
{ name: 'description', content: description }
],
})
</script>
<script setup lang="ts">
const description = ref('My amazing site.')
useSeoMeta({
description
})
</script>
<script setup lang="ts">
const description = ref('My amazing site.')
</script>
<template>
<div>
<Meta name="description" :content="description" />
</div>
</template>
标题模板
¥Title Template
你可以使用 titleTemplate
选项提供动态模板来自定义网站标题。例如,你可以将网站名称添加到每个页面的标题中。
¥You can use the titleTemplate
option to provide a dynamic template for customizing the title of your site. For example, you could add the name of your site to the title of every page.
titleTemplate
可以是字符串(其中 %s
用标题替换),也可以是一个函数。
¥The titleTemplate
can either be a string, where %s
is replaced with the title, or a function.
如果你想使用函数(以实现完全控制),则无法在 nuxt.config
中设置。建议在 app.vue
文件中设置它,它将应用于你网站上的所有页面:
¥If you want to use a function (for full control), then this cannot be set in your nuxt.config
. It is recommended instead to set it within your app.vue
file where it will apply to all pages on your site:
<script setup lang="ts">
useHead({
titleTemplate: (titleChunk) => {
return titleChunk ? `${titleChunk} - Site Title` : 'Site Title';
}
})
</script>
现在,如果你在网站的另一个页面上使用 useHead
将标题设置为 My Page
,则标题将显示为“我的页面” - 浏览器标签页中的“网站标题”。你也可以将 null
传递给 '站点标题' 的默认值。
¥Now, if you set the title to My Page
with useHead
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'.
模板参数
¥Template Params
除了默认的 %s
之外,你还可以使用 templateParams
在 titleTemplate
中提供额外的占位符。这允许更动态的标题生成。
¥You can use templateParams
to provide additional placeholders in your titleTemplate
besides the default %s
. This allows for more dynamic title generation.
<script setup lang="ts">
useHead({
titleTemplate: (titleChunk) => {
return titleChunk ? `${titleChunk} %separator %siteName` : '%siteName';
},
templateParams: {
siteName: 'Site Title',
separator: '-'
}
})
</script>
Body 标签
¥Body Tags
你可以在适用的标签上使用 tagPosition: 'bodyClose'
选项,将它们附加到 <body>
标签的末尾。
¥You can use the tagPosition: 'bodyClose'
option on applicable tags to append them to the end of the <body>
tag.
例如:
¥For example:
<script setup lang="ts">
useHead({
script: [
{
src: 'https://third-party-script.com',
// valid options are: 'head' | 'bodyClose' | 'bodyOpen'
tagPosition: 'bodyClose'
}
]
})
</script>
示例
¥Examples
definePageMeta
使用
¥With definePageMeta
在你的 pages/
目录 中,你可以将 definePageMeta
和 useHead
结合使用,根据当前路由设置元数据。
¥Within your pages/
directory, 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):
<script setup lang="ts">
definePageMeta({
title: 'Some Page'
})
</script>
然后,在你的布局文件中,你可以使用之前设置的路由元数据:
¥And then in your layout file, you might use the route's metadata you have previously set:
<script setup lang="ts">
const route = useRoute()
useHead({
meta: [{ property: 'og:title', content: `App Name - ${route.meta.title}` }]
})
</script>
动态标题
¥Dynamic Title
在下面的示例中,titleTemplate
可以设置为带有 %s
占位符的字符串,也可以设置为 function
,这样可以更灵活地为 Nuxt 应用的每个路由动态设置页面标题:
¥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:
<script setup lang="ts">
useHead({
// as a string,
// where `%s` is replaced with the title
titleTemplate: '%s - Site Title',
})
</script>
<script setup lang="ts">
useHead({
// or as a function
titleTemplate: (productCategory) => {
return productCategory
? `${productCategory} - Site Title`
: 'Site Title'
}
})
</script>
nuxt.config
也可用作设置页面标题的替代方法。但是,nuxt.config
不允许页面标题是动态的。因此,建议在 app.vue
文件中使用 titleTemplate
添加动态标题,然后将其应用于 Nuxt 应用的所有路由。
¥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.
外部 CSS
¥External CSS
以下示例展示了如何使用 useHead
可组合项的 link
属性或使用 <Link>
组件启用 Google 字体:
¥The example below shows how you might enable Google Fonts using either the link
property of the useHead
composable or using the <Link>
component:
<script setup lang="ts">
useHead({
link: [
{
rel: 'preconnect',
href: 'https://fonts.googleapis.com'
},
{
rel: 'stylesheet',
href: 'https://fonts.googleapis.com/css2?family=Roboto&display=swap',
crossorigin: ''
}
]
})
</script>
<template>
<div>
<Link rel="preconnect" href="https://fonts.googleapis.com" />
<Link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Roboto&display=swap" crossorigin="" />
</div>
</template>