六维教程

Nuxt4 SEO 与页面元信息

SEO 决定搜索引擎能否理解你的页面,以及搜索结果里展示什么内容。

SSR 是 Nuxt 的天然优势,页面 HTML 里就有完整内容,搜索引擎可以直接抓取。

页面标题的重要性

浏览器标签页显示标题,搜索引擎结果展示标题和描述。不同页面应该有不同的标题和描述,比如首页是「我的网站」,关于页是「关于我们 - 我的网站」。

useHead 基础用法

在页面中用 useHead 设置元信息:

<!-- app/pages/about.vue -->
<script setup>
useHead({
  title: '关于我们',
  meta: [
    { name: 'description', content: '这里是关于我们的介绍' },
    { name: 'keywords', content: 'Nuxt, Vue, 教程' }
  ]
})
</script>

<template>
  <div>关于页面内容</div>
</template>

刷新页面,浏览器标签页会显示「关于我们」。在网页源码中可以看到自动生成的 <title><meta> 标签。

useSeoMeta 简化写法

useSeoMeta 是专为 SEO 设计的简化版,字段名更直观:

<script setup>
useSeoMeta({
  title: '关于我们',
  description: '这里是关于我们的介绍',
  keywords: 'Nuxt, Vue, 教程',
  ogTitle: '关于我们',          // 社交分享标题
  ogDescription: '分享给朋友看的描述',  // 社交分享描述
  ogImage: '/images/logo.png'   // 社交分享封面图
})
</script>

og 开头的字段是 Open Graph 协议,控制页面被分享到微信、Twitter 等平台时显示的标题、描述和封面图。

动态标题

动态路由页面(如文章详情)标题应该跟随内容变化:

<!-- app/pages/posts/[id].vue -->
<script setup>
const route = useRoute()

const { data: post } = await useFetch(`/api/posts/${route.params.id}`)

// 数据到齐后设置标题
useSeoMeta({
  title: () => `${post.value.title} - 我的网站`,
  description: () => post.value.excerpt
})
</script>

useHeaduseSeoMeta 的字段支持传入函数,函数返回值会自动更新,适合依赖响应式数据的场景。

全局默认设置

公共的默认值放在 app.vue 中设置,所有页面生效,页面级设置会覆盖同名项:

<!-- app/app.vue -->
<script setup>
useSeoMeta({
  title: '我的网站',
  description: '这是我的个人网站',
  ogImage: '/images/logo.png'
})
</script>

<template>
  <NuxtLayout>
    <NuxtPage />
  </NuxtLayout>
</template>

页面里的 useSeoMeta 声明相同的字段(如 title)时,会覆盖全局值,没有声明的字段沿用全局值。这就是 SEO 配置的继承机制。

让页面内容被抓取

元信息之外,正文内容也要可被索引。SSR 模式下正文在 HTML 中,搜索引擎可以直接抓取。要注意两点:

  • 不要依赖客户端 JS 渲染关键内容,搜索爬虫执行 JS 有限
  • 图片要写 alt 属性,方便图片搜索

站点级信息:nuxt-site-config

除了逐页设置标题,还应告诉搜索引擎「整个站点」的基本信息(规范网址、名称、描述)。最省事的做法是用 nuxt-site-config 模块,在 nuxt.config.ts 里写一次 site 块:

// nuxt.config.ts
export default defineNuxtConfig({
  site: {
    url: process.env.NUXT_SITE_URL || 'https://example.com',
    name: '在线小工具',
    description: '免费的在线小工具集合,纯前端处理,无需后端服务',
  },
})

装好模块(npm i nuxt-site-config)并配置后,Nuxt 会自动把它注入到 <head>og:site_namecanonical 等标签里,不用在每个页面重复写。本教程配套的在线工具站就是这么做的。

Sitemap 与 Robots

想让搜索引擎更快发现所有页面,需要 sitemap.xml(站点地图)和 robots.txt(爬取规则)。Nuxt 生态里有现成模块:

// nuxt.config.ts
export default defineNuxtConfig({
  modules: [
    '@nuxtjs/sitemap',
    '@nuxtjs/robots',
  ],

  sitemap: {
    // 自动收集路由生成 sitemap.xml,可设置更新频率和优先级
    defaults: {
      changefreq: 'weekly',
      priority: 0.5,
    },
  },

  robots: {
    // 禁止爬取的内部接口目录
    disallow: ['/api/'],
  },
})

构建后站点根目录会生成 sitemap.xmlrobots.txt。对于动态路由(如 /tools/[slug]),模块会按实际生成的路由自动收录,无需手动枚举。

结构化数据 JSON-LD

除了肉眼可见的标题描述,还可以给搜索引擎「机器可读」的结构化数据,帮助它在搜索结果里展示评分、价格等富媒体信息。常用做法是注入一段 JSON-LD 脚本,Nuxt 里用 useHead 实现:

<!-- app/pages/tools/[slug].vue -->
<script setup>
const tool = useTool() // 假设已拿到当前工具数据

useHead(() => ({
  script: tool.value
    ? [{
        type: 'application/ld+json',
        innerHTML: JSON.stringify({
          '@context': 'https://schema.org',
          '@type': 'SoftwareApplication',
          name: tool.value.name,
          description: tool.value.description,
          applicationCategory: 'UtilitiesApplication',
          operatingSystem: 'Any',
          offers: { '@type': 'Offer', price: '0', priceCurrency: 'CNY' },
        }),
      }]
    : [],
}))
</script>

上面这段来自本项目的工具详情页:每个工具都标注成「SoftwareApplication(免费软件)」,搜索引擎识别后可能展示更丰富的卡片。注意 innerHTML 里的内容要可信,不要拼接用户输入,避免被注入。

静态站点与预渲染

如果你的网站内容几乎不变(博客、官网),可以用静态生成模式。构建时把所有页面预渲染成 HTML,SEO 表现和 SSR 一样好,还能部署到 CDN 上。预渲染配置见配置与部署

SEO 设置速查表

需求 写法
设置页面标题 useSeoMeta({ title: '...' })
设置描述 useSeoMeta({ description: '...' })
社交分享卡片 useSeoMeta({ ogTitle, ogDescription, ogImage })
动态标题 字段传函数,如 title: () => post.value.title
全局默认值 app.vue 中设置
覆盖全局值 页面中声明同名字段
站点级信息 nuxt-site-configsite
站点地图 @nuxtjs/sitemap 模块
爬取规则 @nuxtjs/robots 模块的 robots 配置
结构化数据 useHead 注入 JSON-LD 脚本

一句话总结:SSR 让内容天然可被抓取,useSeoMeta 负责标题、描述和社交分享信息,全局默认写在 app.vue,动态内容传函数。

上一篇
Nuxt4 服务端接口
下一篇
Nuxt4 SSG 静态生成与预渲染