SEO 与元信息
本教程共 50 篇 · 第 42 篇 · 更新于 2026-08-08 · 约 8 分钟阅读
本节目标:理解 Nuxt 的头部元信息管理机制,能用
useHead/useSeoMeta设置标题、描述、OG 标签,让网站在搜索引擎和社交分享里表现更好。
42-1
你在微信里分享一个链接,对方看到的卡片标题、描述、缩略图,就是「元信息(meta)」在起作用。搜索引擎抓取你的页面,靠的也是 <title>、<meta name="description">、Open Graph(OG)这些标签。Nuxt 由 Unhead 提供头部管理能力,让你在 Vue 里用代码控制这些标签,而不是手写一堆 <head>。
NoteNuxt 默认就给了你合理的
<meta charset="utf-8">和<meta viewport>,开箱即用的基础 SEO 已经具备。你要做的是按页面补充更具体的信息。
42-2
不随页面变化的内容(默认标题、语言、favicon)适合写在 nuxt.config.ts 的 app.head:
export default defineNuxtConfig({
app: {
head: {
title: 'Nuxt',
htmlAttrs: {
lang: 'zh-CN',
},
link: [
{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' },
],
},
},
})
这里设置的标签是静态的,不支持响应式。需要「按页面/按数据」变化的,留给 useHead。
42-3
useHead 可以在组件里动态设置标签,所有字段都支持响应式(传 ref、computed、getter 都行):
<script setup lang="ts">
const description = ref('我的精彩网站。')
useHead({
title: '我的应用',
meta: [
{ name: 'description', content: description },
],
bodyAttrs: {
class: 'test',
},
script: [
{ innerHTML: 'console.log(\'Hello world\')' },
],
})
</script>
把 description 换成 ref,标题和描述会随它自动更新。
42-4
useSeoMeta 是专为 SEO 设计的,它让你以对象形式写标签,并且带完整类型检查和自动补全,能避免把 name 和 property 写混这类低级错误:
<script setup lang="ts">
useSeoMeta({
title: '我的精彩网站',
ogTitle: '我的精彩网站',
description: '这是我的精彩网站,让我为你详细介绍。',
ogDescription: '这是我的精彩网站,让我为你详细介绍。',
ogImage: 'https://example.com/image.png',
twitterCard: 'summary_large_image',
})
</script>
ogTitle、ogImage、twitterCard 这些就是社交平台(微信、X、Facebook)读取的 Open Graph 标签。填好它们,分享出来的卡片才好看。
Tip社交分享卡片的图建议用
https://绝对地址,ogImage用相对路径在部分平台可能不生效。
42-5
你肯定见过「文章标题 - 我的站点」这种格式。用 titleTemplate 就能给全站标题加后缀:
<script setup lang="ts">
useHead({
titleTemplate: (titleChunk) => {
return titleChunk ? `${titleChunk} - 码上学` : '码上学'
},
})
</script>
之后某页面 useHead({ title: '第一章' }),浏览器标签就显示「第一章 - 码上学」。titleTemplate 也支持 '%s - 码上学' 这种字符串写法,%s 会被标题替换。
42-6
不喜欢在脚本里写、更想用模板?Nuxt 提供了一组大写首字母的组件:<Title>、<Meta>、<Link>、<Head>、<Body>、<Html> 等。
<script setup lang="ts">
const title = ref('Hello World')
</script>
<template>
<div>
<Head>
<Title>{{ title }}</Title>
<Meta name="description" :content="title" />
</Head>
<h1>{{ title }}</h1>
</div>
</template>
Note组件首字母大写(如
<Meta>而非<meta>)是为了不和原生 HTML 标签冲突,也方便 Nuxt 识别并处理去重。建议把标签包在<Head>里,去重更直观。
42-7
在 pages/ 里,可以结合 definePageMeta 和 useHead 按当前路由设置 OG 信息:
<script setup lang="ts">
definePageMeta({
title: '某个页面',
})
</script>
<script setup lang="ts">
const route = useRoute()
useHead({
meta: [
{ property: 'og:title', content: `码上学 - ${route.meta.title}` },
],
})
</script>
Warning
definePageMeta里的title是构建时提取的宏,不能在运行时动态赋值。动态标题要用useHead的titleTemplate在app.vue里统一处理。
42-8
Nuxt 3 与 Nuxt 4 的 useHead/useSeoMeta/头部组件 API 完全一致。唯一的目录差异是这些代码所在文件位于 app/ 下(Nuxt 4)。OG、Twitter 标签的语义双方相同。
42-9
两个都能设头部,怎么选?useHead 更通用,什么标签都能写,但字段是松散的对象,拼错 name/property 不会报错。useSeoMeta 是 useHead 的「SEO 专用版」:它的键名是固定且带类型的(title、description、ogTitle、ogImage…),写错单词编辑器直接标红,还能自动把 ogTitle 映射到正确的 property="og:title"。
日常建议:纯 SEO 字段用 useSeoMeta,要塞自定义 <script>、<body> class 这类非 SEO 的东西再上 useHead。两者可以在同一个组件里同时用,不冲突。
42-10
社交平台(微信、X、Facebook)读的是 Open Graph 标签。最少要填四项:og:title、og:description、og:image、og:type。og:type 一般是 website 或 article;文章页设成 article 还能加 article:section、article:published_time 等。
Tip
og:image用绝对地址(https://...),部分平台不认相对路径。图建议 1200×630 左右,太大加载慢、太小被拉伸。Twitter 卡片则靠twitter:card和twitter:image控制。
42-11
- 只在
app.vue写死一个标题,所有页面都叫「我的网站」——应该用useSeoMeta按页面动态设。 - 忘记
lang="zh-CN":搜索引擎靠它判断语言,写在app.head.htmlAttrs里。 - 把
description写成和标题一模一样——两者作用不同,描述要补全一句话。 - 以为 SSR 自动帮你发 OG 到社交平台——OG 是静态/构建期标签,动态内容要用
useSeoMeta注入才会进 HTML。 实际项目里,标题和描述常常来自接口数据。比如文章页,标题要用文章标题,描述要用文章摘要。做法是先await useFetch拿到数据,再把数据传给useSeoMeta:在<script setup>里取回data后,调用useSeoMeta({ title: data.value.title, description: data.value.summary })。因为useSeoMeta支持传 ref,数据变化时标签会跟着更新,不用写死。
另外,同一篇内容可能被多个 URL 访问到(带不同参数的链接、大小写不同的路径),建议加一个 canonical 标签指回规范地址,避免搜索引擎把同一篇内容当成多页、分散收录权重。用 useHead 加 <link rel="canonical" href="..."> 即可,href 用绝对地址最稳。
Tip动态 SEO 最容易出的错是「数据还没回来就渲染了标签」。把
useSeoMeta放在await useFetch之后调用,确保标签用的是真实数据,而不是初始的null。
42-12
静态默认标签放 nuxt.config 的 app.head;页面级动态标签用 useHead 或类型安全的 useSeoMeta;titleTemplate 统一标题格式;社交卡片靠 OG 标签。下一章我们看如何把页面在构建时渲染成静态文件:预渲染与混合渲染。
42-7 SEO 的长期维护策略
SEO 不是一次性的工作,而是需要持续维护的。随着内容增加和页面结构变化,元信息可能变得过时或不准确。建议建立一套检查机制,定期审查关键页面的标题、描述、开放图谱标签是否仍然合适。
在 Nuxt 项目里,可以把 SEO 相关的逻辑封装成一个组合式函数(如 useSeo),统一处理标题拼接、描述截断、默认图片等逻辑。这样每个页面只需要传入核心信息,其余的由组合式函数自动补全,减少遗漏的风险。
另外,搜索引擎的算法在不断更新。关注 Google Search Central 和 Bing Webmaster 的官方公告,了解最新的 SEO 最佳实践。Nuxt 的 SSR 和 SSG 能力为 SEO 提供了天然优势,但内容质量、页面速度、移动端适配等因素同样重要。
42-8 结构化数据与富媒体展示
除了基本的元信息标签,结构化数据(Structured Data)是 SEO 的另一个重要维度。通过在页面里嵌入 JSON-LD 格式的结构化数据,你可以告诉搜索引擎这个页面的内容类型(文章、产品、FAQ 等),帮助搜索引擎更准确地理解页面。
在 Nuxt 里,可以通过 useHead 动态插入 JSON-LD 脚本。把结构化数据的生成逻辑封装成组合式函数,不同页面类型调用不同的函数,自动生成对应的结构化数据。
结构化数据不仅帮助搜索引擎,还能让你的页面在搜索结果里以更丰富的形式展示(如星级评分、面包屑导航、FAQ 折叠面板)。这些富媒体展示能显著提高点击率。