Nuxt 3 SEO 优化最佳实践指南

HTMLPAGE 团队
20分钟 分钟阅读

系统掌握 Nuxt 3 中的 SEO 优化技术,从元标签管理、结构化数据到性能优化,构建搜索引擎友好的现代 Web 应用。

#Nuxt #SEO #SSR #搜索引擎优化 #元标签

为什么 Nuxt 天生适合 SEO

Nuxt 3 通过服务端渲染(SSR)解决了传统 SPA 应用 SEO 的核心痛点。搜索引擎爬虫可以直接获取完整的 HTML 内容,无需执行 JavaScript。

渲染模式SEO 友好度适用场景
SSR⭐⭐⭐⭐⭐内容型网站、电商、博客
SSG⭐⭐⭐⭐⭐文档站、营销页、静态博客
ISR⭐⭐⭐⭐频繁更新但可接受延迟的内容
CSR⭐⭐后台管理、用户私有页面

元标签管理策略

使用 useHead 组合式函数

Nuxt 提供了 useHead 来管理页面元信息。这个函数支持响应式数据,页面数据变化时元标签会自动更新:

// pages/products/[id].vue
const { data: product } = await useFetch(`/api/products/${route.params.id}`)

useHead({
  title: () => `${product.value?.name} - 优选商城`,
  meta: [
    { 
      name: 'description', 
      content: () => product.value?.description?.slice(0, 160) 
    },
    // Open Graph 标签(社交分享)
    { property: 'og:title', content: () => product.value?.name },
    { property: 'og:image', content: () => product.value?.image },
    { property: 'og:type', content: 'product' }
  ]
})

关键说明: 使用箭头函数包裹动态值,确保数据加载后元标签能正确更新。如果直接传入 product.value?.name,在数据加载前会是 undefined。

全局默认配置

nuxt.config.ts 中设置全站默认元信息,各页面只需覆盖特定字段:

// nuxt.config.ts
export default defineNuxtConfig({
  app: {
    head: {
      titleTemplate: '%s - 网站名称',
      htmlAttrs: { lang: 'zh-CN' },
      meta: [
        { charset: 'utf-8' },
        { name: 'viewport', content: 'width=device-width, initial-scale=1' },
        { name: 'robots', content: 'index, follow' }
      ],
      link: [
        { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }
      ]
    }
  }
})

titleTemplate 中的 %s 会被各页面的标题替换,实现统一的标题格式。

结构化数据实现

结构化数据帮助搜索引擎理解页面内容,可能触发富媒体搜索结果。

使用 useSchemaOrg 模块

安装官方 SEO 模块后,可以声明式地添加结构化数据:

// 文章页面示例
useSchemaOrg([
  defineArticle({
    headline: article.value.title,
    description: article.value.description,
    image: article.value.coverImage,
    datePublished: article.value.createdAt,
    dateModified: article.value.updatedAt,
    author: {
      name: article.value.author.name,
      url: article.value.author.profileUrl
    }
  })
])

手动注入 JSON-LD

对于模块未覆盖的场景,可以手动添加:

useHead({
  script: [
    {
      type: 'application/ld+json',
      innerHTML: JSON.stringify({
        '@context': 'https://schema.org',
        '@type': 'Product',
        name: product.value.name,
        image: product.value.images,
        offers: {
          '@type': 'Offer',
          price: product.value.price,
          priceCurrency: 'CNY',
          availability: product.value.inStock 
            ? 'https://schema.org/InStock' 
            : 'https://schema.org/OutOfStock'
        }
      })
    }
  ]
})

规范链接与重复内容处理

Canonical 标签

对于可能存在重复内容的页面(如带参数的商品列表),设置规范链接:

// 商品列表页,忽略筛选参数
const canonicalUrl = computed(() => {
  const base = useRuntimeConfig().public.siteUrl
  return `${base}/products/${route.params.category}`
})

useHead({
  link: [{ rel: 'canonical', href: canonicalUrl }]
})

分页与无限滚动

分页内容需要正确设置 rel="prev"rel="next"

const page = computed(() => Number(route.query.page) || 1)
const totalPages = computed(() => Math.ceil(total.value / pageSize))

useHead({
  link: [
    // 上一页
    page.value > 1 && {
      rel: 'prev',
      href: `${baseUrl}?page=${page.value - 1}`
    },
    // 下一页
    page.value < totalPages.value && {
      rel: 'next', 
      href: `${baseUrl}?page=${page.value + 1}`
    }
  ].filter(Boolean)
})

Sitemap 与 Robots 配置

动态生成 Sitemap

使用 @nuxtjs/sitemap 模块自动生成站点地图:

// nuxt.config.ts
export default defineNuxtConfig({
  modules: ['@nuxtjs/sitemap'],
  
  sitemap: {
    hostname: 'https://example.com',
    // 动态路由需要手动提供
    routes: async () => {
      const products = await $fetch('/api/products/slugs')
      return products.map(slug => `/products/${slug}`)
    }
  }
})

Robots.txt 控制

// server/routes/robots.txt.ts
export default defineEventHandler(() => {
  return `User-agent: *
Allow: /
Disallow: /admin/
Disallow: /api/
Sitemap: https://example.com/sitemap.xml`
})

性能优化对 SEO 的影响

Core Web Vitals 已成为 Google 排名因素。Nuxt 提供多种优化手段:

图片优化

<template>
  <NuxtImg
    :src="product.image"
    :alt="product.name"
    width="400"
    height="300"
    loading="lazy"
    format="webp"
    sizes="sm:100vw md:50vw lg:400px"
  />
</template>

优化要点:

  • loading="lazy" 延迟加载非首屏图片
  • format="webp" 自动转换为现代格式
  • 始终提供 alt 属性,描述图片内容

预渲染关键页面

对于 SEO 重要但数据变化不频繁的页面,使用 SSG 预渲染:

// nuxt.config.ts
export default defineNuxtConfig({
  routeRules: {
    // 首页预渲染
    '/': { prerender: true },
    // 分类页每小时重新生成
    '/categories/**': { isr: 3600 },
    // 用户中心纯客户端渲染
    '/account/**': { ssr: false }
  }
})

多语言 SEO

hreflang 标签配置

多语言网站需要告知搜索引擎各语言版本的对应关系:

// 使用 @nuxtjs/i18n 模块时自动处理
// 手动配置示例
const { locale, locales } = useI18n()

useHead({
  link: locales.value.map(loc => ({
    rel: 'alternate',
    hreflang: loc.code,
    href: `https://example.com/${loc.code}${route.path}`
  }))
})

SEO 审计清单

在发布前检查以下要点:

检查项工具标准
页面可索引性Google Search Console无索引错误
元标签完整性浏览器 DevToolstitle < 60字符,description 50-160字符
结构化数据Schema Markup Validator无错误警告
移动友好性Mobile-Friendly Test通过测试
页面速度PageSpeed InsightsLCP < 2.5s

实用技巧

  1. 避免重复标题:每个页面应有唯一的 title 和 description
  2. 使用语义化 HTML:正确使用 h1-h6、article、nav 等标签
  3. 图片 ALT 属性:所有图片都应有描述性的 alt 文本
  4. 内部链接:使用 <NuxtLink> 而非 <a> 标签,确保 SEO 和预取优化
  5. 404 处理:为不存在的页面返回正确的 404 状态码
// 商品详情页 404 处理
const { data: product } = await useFetch(`/api/products/${id}`)

if (!product.value) {
  throw createError({
    statusCode: 404,
    statusMessage: '商品不存在'
  })
}

通过以上实践,你的 Nuxt 应用将具备出色的搜索引擎可见性,为用户获取自然流量打下坚实基础。