Nuxt实战(4)-SEO、SiteMap、I18N国际化配置

2025年9月4日
约 10 分钟阅读时间
By 麦兜九天 & Tianyang Wang

目录

🎯 概述

在现代 Web 开发中,SEO 优化、网站地图生成和国际化支持是构建高质量应用的重要组成部分。本章将详细介绍如何在 Nuxt 游戏社区项目中配置这些功能,为游戏讨论&创作社区提升搜索引擎友好性和用户体验。

📋 本章目标

  • 🔍 SEO 优化-配置元数据、Open Graph、Twitter Cards
  • 🗺️ SiteMap 生成-自动生成和管理网站地图
  • 🌍 I18N 国际化-支持多语言切换和本地化
  • 📊 数据统计-集成 Google Analytics、Clarity 等分析工具
  • 🤖 搜索引擎-配置 robots.txt 和爬虫规则

🔍 SEO 搜索引擎优化

📦 安装 SEO 模块

Nuxt SEO 是一个强大的模块集合,包含了搜索引擎优化所需的所有工具-

# 安装 Nuxt SEO 模块
npx nuxi@latest module add seo

🏗️ 基础 SEO 配置

1. 全局配置 (nuxt.config.ts)

export default defineNuxtConfig({
  // 站点基础信息
  site: {
    url: 'https://game-community.cn',
    name: '游戏讨论&创作社区',
    description: '专注游戏讨论、创作分享和玩家交流的综合性游戏社区平台',
    defaultLocale: 'zh-CN', // 默认语言
    trailingSlash: false, // URL 是否包含尾部斜杠
  },
 
  // 应用配置
  app: {
    head: {
      title: '游戏讨论&创作社区',
      titleTemplate: '%s - 游戏讨论&创作社区',
      meta: [
        { name: 'keywords', content: '游戏社区,游戏讨论,游戏创作,玩家交流,游戏攻略,游戏评测' },
        { name: 'description', content: '专注游戏讨论、创作分享和玩家交流的综合性游戏社区平台' },
        { name: 'author', content: '游戏社区团队' },
        { name: 'viewport', content: 'width=device-width, initial-scale=1' },
        { charset: 'utf-8' }
      ],
      link: [
        { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' },
        { rel: 'canonical', href: 'https://game-community.cn' }
      ]
    }
  }
})

2. 页面级 SEO 配置

使用 useHead 组合函数
<script setup lang="ts">
// 基础页面 SEO
useHead({
  title: '首页',
  meta: [
    { name: 'description', content: '欢迎来到游戏讨论&创作社区首页,发现精彩游戏内容' },
    { name: 'keywords', content: '游戏首页,游戏社区,游戏讨论,游戏创作' }
  ],
  link: [
    { rel: 'canonical', href: 'https://game-community.cn/' }
  ]
})
</script>
使用 useSeoMeta 组合函数
<script setup lang="ts">
// 完整的 SEO 元数据配置
useSeoMeta({
  // 基础信息
  title: '游戏讨论&创作社区 - 玩家的精神家园',
  description: '专注游戏讨论、创作分享和玩家交流的综合性游戏社区平台,提供游戏攻略、评测、创作工具等服务',
  keywords: '游戏社区,游戏讨论,游戏创作,玩家交流,游戏攻略,游戏评测,游戏资讯',
  
  // Open Graph (Facebook, LinkedIn 等)
  ogTitle: '游戏讨论&创作社区 - 玩家的精神家园',
  ogDescription: '专注游戏讨论、创作分享和玩家交流的综合性游戏社区平台,提供游戏攻略、评测、创作工具等服务',
  ogImage: 'https://game-community.cn/og-image.jpg',
  ogUrl: 'https://game-community.cn',
  ogType: 'website',
  ogSiteName: '游戏讨论&创作社区',
  
  // Twitter Cards
  twitterCard: 'summary_large_image',
  twitterSite: '@gamecommunity',
  twitterCreator: '@gameteam',
  twitterTitle: '游戏讨论&创作社区 - 玩家的精神家园',
  twitterDescription: '专注游戏讨论、创作分享和玩家交流的综合性游戏社区平台',
  twitterImage: 'https://game-community.cn/twitter-image.jpg',
  
  // 其他元数据
  robots: 'index, follow',
  googlebot: 'index, follow',
  author: '游戏社区团队',
  publisher: '游戏讨论&创作社区'
})
</script>
使用 definePageMeta 设置页面元数据
<script setup lang="ts">
// 页面级元数据定义
definePageMeta({
  title: '关于我们',
  description: '了解游戏讨论&创作社区团队和我们的使命',
  layout: 'default'
})
</script>

3. 动态 SEO 配置

<script setup lang="ts">
// 动态标题模板
useHead({
  titleTemplate: (title) => {
    return title ? `${title} - 游戏讨论&创作社区` : '游戏讨论&创作社区 - 玩家的精神家园'
  }
})
 
// 根据路由动态设置 SEO
const route = useRoute()
const { data: pageData } = await $fetch(`/api/pages${route.path}`)
 
useSeoMeta({
  title: pageData.title,
  description: pageData.description,
  ogImage: pageData.image || '/default-og.jpg'
})
</script>

🤖 Robots 爬虫配置

1. 全局 Robots 配置

export default defineNuxtConfig({
  // 站点索引配置
  site: {
    indexable: true // 允许搜索引擎索引
  },
 
  // Robots 规则
  robots: {
    // 允许所有爬虫
    UserAgent: '*',
    // 禁止访问的路径
    Disallow: ['/admin', '/api', '/private'],
    // 允许访问的路径
    Allow: ['/api/public'],
    // 网站地图位置
    Sitemap: 'https://game-community.cn/sitemap.xml'
  },
 
  // 路由规则
  routeRules: {
    // 禁止管理后台被索引
    '/admin/**': { robots: false },
    // 禁止 API 路由被索引
    '/api/**': { robots: false },
    // 首页高优先级
    '/': { sitemap: { priority: 1.0, changefreq: 'daily' } },
    // 博客页面
    '/blog/**': { sitemap: { priority: 0.8, changefreq: 'weekly' } }
  }
})

2. 页面级 Robots 配置

<script setup lang="ts">
// 禁止特定页面被索引
defineRouteRules({
  robots: false, // 禁止索引
  sitemap: false // 不包含在网站地图中
})
 
// 或者使用 useSeoMeta
useSeoMeta({
  robots: 'noindex, nofollow' // 禁止索引和跟踪链接
})
</script>

🗺️ SiteMap 网站地图配置

📋 基础配置

export default defineNuxtConfig({
  sitemap: {
    // 网站地图 URL
    hostname: 'https://game-community.cn',
    
    // 缓存配置
    cacheMaxAgeSeconds: 24 * 60 * 60, // 24小时缓存
    
    // 自动检测最后修改时间
    autoLastmod: true,
    
    // 默认配置
    defaults: {
      changefreq: 'weekly',
      priority: 0.5,
      lastmod: new Date().toISOString()
    },
 
    // 包含的路径
    include: [
      '/games/**',
      '/discussions/**',
      '/creations/**',
      '/guides/**',
      '/reviews/**',
      '/about'
    ],
 
    // 排除的路径
    exclude: [
      '/admin/**',
      '/api/**',
      '/private/**',
      '/_nuxt/**'
    ]
  }
})

🎨 自定义网站地图样式

export default defineNuxtConfig({
  sitemap: {
    // 自定义 XSL 样式表
    xsl: '/sitemap.xsl',
    
    // 自定义列配置
    xslColumns: [
      { label: 'URL', width: '50%' },
      { label: '最后修改', select: 'sitemap:lastmod', width: '25%' },
      { label: '优先级', select: 'sitemap:priority', width: '12.5%' },
      { label: '更新频率', select: 'sitemap:changefreq', width: '12.5%' }
    ],
 
    // 自定义提示信息
    xslTips: true
  }
})

📄 动态网站地图生成

1. 创建动态路由网站地图

// server/api/sitemap.ts
export default defineEventHandler(async (event) => {
  // 获取动态内容
  const posts = await $fetch('/api/posts')
  const projects = await $fetch('/api/projects')
  
  const urls = [
    // 静态页面
    {
      loc: '/',
      lastmod: new Date(),
      changefreq: 'daily',
      priority: 1.0
    },
    
    // 动态博客页面
    ...posts.map(post => ({
      loc: `/blog/${post.slug}`,
      lastmod: new Date(post.updatedAt),
      changefreq: 'weekly',
      priority: 0.8
    })),
    
    // 动态项目页面
    ...projects.map(project => ({
      loc: `/projects/${project.slug}`,
      lastmod: new Date(project.updatedAt),
      changefreq: 'monthly',
      priority: 0.6
    }))
  ]
 
  return urls
})

2. 页面级网站地图配置

<script setup lang="ts">
// 设置页面在网站地图中的属性
defineRouteRules({
  sitemap: {
    changefreq: 'daily',
    priority: 0.9,
    lastmod: new Date('2024-01-01')
  }
})
 
// 使用 SEO 元数据设置最后修改时间
useSeoMeta({
  articleModifiedTime: '2024-01-01T00:00:00.000Z'
})
</script>

🔄 多语言网站地图

export default defineNuxtConfig({
  sitemap: {
    // 多语言支持
    i18n: true,
    
    // 为每种语言生成单独的网站地图
    sitemaps: {
      'zh-CN': {
        hostname: 'https://game-community.cn',
        defaults: { changefreq: 'weekly', priority: 0.5 }
      },
      'zh-TW': {
        hostname: 'https://tw.game-community.cn',
        defaults: { changefreq: 'weekly', priority: 0.5 }
      }
    }
  }
})

🌍 I18N 国际化配置

📦 安装国际化模块

# 安装 Nuxt I18N 模块
npx nuxi@latest module add i18n

🏗️ 基础国际化配置

1. 配置文件 (nuxt.config.ts)

export default defineNuxtConfig({
  modules: ['@nuxtjs/i18n'],
  
  i18n: {
    // 支持的语言列表
    locales: [
      {
        code: 'zh-CN',
        name: '简体中文',
        iso: 'zh-CN',
        file: 'zh-CN.json',
        dir: 'ltr'
      },
      {
        code: 'zh-TW',
        name: '繁體中文',
        iso: 'zh-TW',
        file: 'zh-TW.json',
        dir: 'ltr'
      }
    ],
 
    // 默认语言
    defaultLocale: 'zh-CN',
 
    // 语言文件目录
    langDir: 'locales/',
 
    // 路由策略
    strategy: 'prefix_except_default', // 默认语言不加前缀
 
    // 检测用户语言
    detectBrowserLanguage: {
      useCookie: true,
      cookieKey: 'i18n_redirected',
      redirectOn: 'root',
      alwaysRedirect: false,
      fallbackLocale: 'zh-CN'
    },
 
    // SEO 配置
    seo: true,
    
    // 编译优化
    compilation: {
      strictMessage: false,
      escapeHtml: false
    }
  }
})

2. 语言文件结构

创建 locales/ 目录并添加语言文件-

// locales/zh-CN.json
{
  "nav": {
    "home": "首页",
    "games": "游戏",
    "discussions": "讨论",
    "creations": "创作",
    "guides": "攻略",
    "reviews": "评测",
    "about": "关于"
  },
  "common": {
    "loading": "加载中...",
    "error": "出错了",
    "retry": "重试",
    "cancel": "取消",
    "confirm": "确认",
    "search": "搜索",
    "login": "登录",
    "register": "注册"
  },
  "home": {
    "title": "欢迎来到游戏讨论&创作社区",
    "subtitle": "玩家的精神家园",
    "description": "专注游戏讨论、创作分享和玩家交流的综合性游戏社区平台"
  },
  "games": {
    "title": "游戏库",
    "hotGames": "热门游戏",
    "newGames": "新游戏",
    "categories": "游戏分类"
  },
  "discussions": {
    "title": "游戏讨论",
    "hotTopics": "热门话题",
    "latestPosts": "最新帖子",
    "reply": "回复",
    "like": "点赞"
  },
  "creations": {
    "title": "创作中心",
    "myWorks": "我的作品",
    "upload": "上传作品",
    "gallery": "作品展示"
  }
}
// locales/zh-TW.json
{
  "nav": {
    "home": "首頁",
    "games": "遊戲",
    "discussions": "討論",
    "creations": "創作",
    "guides": "攻略",
    "reviews": "評測",
    "about": "關於"
  },
  "common": {
    "loading": "載入中...",
    "error": "出錯了",
    "retry": "重試",
    "cancel": "取消",
    "confirm": "確認",
    "search": "搜尋",
    "login": "登入",
    "register": "註冊"
  },
  "home": {
    "title": "歡迎來到遊戲討論&創作社群",
    "subtitle": "玩家的精神家園",
    "description": "專注遊戲討論、創作分享和玩家交流的綜合性遊戲社群平台"
  },
  "games": {
    "title": "遊戲庫",
    "hotGames": "熱門遊戲",
    "newGames": "新遊戲",
    "categories": "遊戲分類"
  },
  "discussions": {
    "title": "遊戲討論",
    "hotTopics": "熱門話題",
    "latestPosts": "最新貼文",
    "reply": "回覆",
    "like": "按讚"
  },
  "creations": {
    "title": "創作中心",
    "myWorks": "我的作品",
    "upload": "上傳作品",
    "gallery": "作品展示"
  }
}

🎨 组件中使用国际化

1. 基础用法

<template>
  <div>
    <!-- 基础翻译 -->
    <h1>{{ $t('home.title') }}</h1>
    <p>{{ $t('home.description') }}</p>
    
    <!-- 带参数的翻译 -->
    <p>{{ $t('welcome.message', { name: userName }) }}</p>
    
    <!-- 复数形式 -->
    <p>{{ $tc('items.count', itemCount, { count: itemCount }) }}</p>
    
    <!-- 当前语言信息 -->
    <p>{{ $i18n.locale }} - {{ $i18n.locales.find(l => l.code === $i18n.locale)?.name }}</p>
  </div>
</template>
 
<script setup lang="ts">
const { t, locale, locales } = useI18n()
const userName = ref('张三')
const itemCount = ref(5)
 
// 响应式翻译
const title = computed(() => t('home.title'))
 
// 切换语言
const switchLanguage = (newLocale: string) => {
  locale.value = newLocale
}
</script>

2. 语言切换组件

<!-- components/LanguageSwitcher.vue -->
<template>
  <UDropdown>
    <UButton
      :label="currentLocale?.name"
      :icon="currentLocale?.flag"
      variant="ghost"
      size="sm"
    />
    
    <template #content>
      <UDropdownItem
        v-for="locale in availableLocales"
        :key="locale.code"
        :label="locale.name"
        :icon="locale.flag"
        @click="switchLocale(locale.code)"
      />
    </template>
  </UDropdown>
</template>
 
<script setup lang="ts">
const { locale, locales, setLocale } = useI18n()
 
// 当前语言
const currentLocale = computed(() => 
  locales.value.find(l => l.code === locale.value)
)
 
// 可用语言列表
const availableLocales = computed(() => 
  locales.value.filter(l => l.code !== locale.value)
)
 
// 切换语言
const switchLocale = async (newLocale: string) => {
  await setLocale(newLocale)
  
  // 可选-刷新页面或重新获取数据
  await refreshCookie('i18n_redirected')
}
</script>

🔗 路由国际化

1. 自定义路由名称

// nuxt.config.ts
export default defineNuxtConfig({
  i18n: {
    customRoutes: 'config',
    pages: {
      about: {
        'zh-CN': '/about',
        'zh-TW': '/about'
      },
      'games/index': {
        'zh-CN': '/games',
        'zh-TW': '/games'
      },
      'games/[id]': {
        'zh-CN': '/games/[id]',
        'zh-TW': '/games/[id]'
      },
      'discussions/index': {
        'zh-CN': '/discussions',
        'zh-TW': '/discussions'
      },
      'discussions/[id]': {
        'zh-CN': '/discussions/[id]',
        'zh-TW': '/discussions/[id]'
      },
      'creations/index': {
        'zh-CN': '/creations',
        'zh-TW': '/creations'
      }
    }
  }
})

2. 路由链接国际化

<template>
  <nav>
    <!-- 使用 localePath 生成本地化链接 -->
    <NuxtLink :to="localePath('/')">
      {{ $t('nav.home') }}
    </NuxtLink>
    
    <NuxtLink :to="localePath('/games')">
      {{ $t('nav.games') }}
    </NuxtLink>
    
    <NuxtLink :to="localePath('/discussions')">
      {{ $t('nav.discussions') }}
    </NuxtLink>
    
    <NuxtLink :to="localePath('/creations')">
      {{ $t('nav.creations') }}
    </NuxtLink>
    
    <!-- 切换到其他语言的相同页面 -->
    <NuxtLink :to="switchLocalePath('zh-TW')">
      繁體中文
    </NuxtLink>
  </nav>
</template>
 
<script setup lang="ts">
const { localePath, switchLocalePath } = useI18n()
</script>

📱 SEO 国际化

<script setup lang="ts">
const { t, locale } = useI18n()
 
// 多语言 SEO 配置
useSeoMeta({
  title: t('seo.title'),
  description: t('seo.description'),
  ogTitle: t('seo.ogTitle'),
  ogDescription: t('seo.ogDescription'),
  
  // 语言标识
  ogLocale: locale.value,
  
  // 替代语言版本
  ogLocaleAlternate: ['zh-CN', 'zh-TW']
})
 
// 设置 HTML lang 属性
useHead({
  htmlAttrs: {
    lang: locale.value
  }
})
</script>

🎨 Open Graph 图片生成

📦 配置 OG Image

// nuxt.config.ts
export default defineNuxtConfig({
  ogImage: {
    // 默认配置
    defaults: {
      width: 1200,
      height: 630,
      extension: 'png',
      cacheMaxAgeSeconds: 60 * 60 * 24 * 7 // 7天缓存
    },
    
    // 字体配置
    fonts: [
      'Inter:400',
      'Inter:700'
    ],
    
    // 组件目录
    componentDirs: ['~/components/OgImage']
  }
})

🎨 自定义 OG 图片组件

<!-- components/OgImage/Default.vue -->
<template>
  <div class="w-full h-full bg-gradient-to-br from-blue-600 to-purple-700 flex items-center justify-center">
    <div class="text-center text-white">
      <h1 class="text-6xl font-bold mb-4">
        {{ title || 'Dream Site' }}
      </h1>
      <p class="text-2xl opacity-90">
        {{ description }}
      </p>
    </div>
  </div>
</template>
 
<script setup lang="ts">
defineProps<{
  title?: string
  description?: string
}>()
</script>

📄 页面中使用 OG 图片

<script setup lang="ts">
// 使用默认模板
defineOgImageComponent('Default')
 
// 使用自定义参数
defineOgImageComponent('Default', {
  title: '技术博客',
  description: '分享最新的开发技术和经验'
})
 
// 动态生成
const route = useRoute()
const { data: post } = await $fetch(`/api/posts/${route.params.slug}`)
 
defineOgImageComponent('BlogPost', {
  title: post.title,
  description: post.excerpt,
  image: post.coverImage,
  author: post.author.name,
  publishedAt: post.publishedAt
})
</script>

📋 完整配置示例

🔧 nuxt.config.ts 完整配置

export default defineNuxtConfig({
  // 基础模块
  modules: [
    '@nuxtjs/seo',
    '@nuxtjs/i18n',
    'nuxt-gtag',
    'nuxt-clarity-analytics'
  ],
 
  // 站点配置
  site: {
    url: 'https://game-community.cn',
    name: '游戏讨论&创作社区',
    description: '专注游戏讨论、创作分享和玩家交流的综合性游戏社区平台',
    defaultLocale: 'zh-CN',
    indexable: true
  },
 
  // SEO 配置
  app: {
    head: {
      title: '游戏讨论&创作社区',
      titleTemplate: '%s - 游戏讨论&创作社区',
      meta: [
        { name: 'keywords', content: '游戏社区,游戏讨论,游戏创作,玩家交流,游戏攻略,游戏评测' },
        { name: 'description', content: '专注游戏讨论、创作分享和玩家交流的综合性游戏社区平台' },
        { name: 'author', content: '游戏社区团队' }
      ]
    }
  },
 
  // 国际化配置
  i18n: {
    locales: [
      { code: 'zh-CN', name: '简体中文', file: 'zh-CN.json' },
      { code: 'zh-TW', name: '繁體中文', file: 'zh-TW.json' }
    ],
    defaultLocale: 'zh-CN',
    langDir: 'locales/',
    strategy: 'prefix_except_default',
    seo: true
  },
 
  // 网站地图配置
  sitemap: {
    hostname: 'https://game-community.cn',
    cacheMaxAgeSeconds: 24 * 60 * 60,
    autoLastmod: true,
    exclude: ['/admin/**', '/api/**']
  },
 
  // Robots 配置
  robots: {
    UserAgent: '*',
    Disallow: ['/admin', '/api/private'],
    Sitemap: 'https://game-community.cn/sitemap.xml'
  },
 
  // 路由规则
  routeRules: {
    '/': { sitemap: { priority: 1.0, changefreq: 'daily' } },
    '/games/**': { sitemap: { priority: 0.9, changefreq: 'daily' } },
    '/discussions/**': { sitemap: { priority: 0.8, changefreq: 'hourly' } },
    '/creations/**': { sitemap: { priority: 0.8, changefreq: 'weekly' } },
    '/guides/**': { sitemap: { priority: 0.7, changefreq: 'weekly' } },
    '/reviews/**': { sitemap: { priority: 0.7, changefreq: 'weekly' } },
    '/admin/**': { robots: false, sitemap: false }
  },
 
  // Google Analytics
  gtag: {
    id: 'G-XXXXXXXXXX'
  },
 
  // 运行时配置
  runtimeConfig: {
    public: {
      siteUrl: 'https://game-community.cn',
      clarityId: process.env.MICROSOFT_CLARITY_ID
    }
  }
})

📝 总结

本章详细介绍了 Nuxt 项目中 SEO 优化、网站地图生成和国际化配置的完整实现方案-

✅ 完成的功能

  1. 🔍 SEO 优化

    • 元数据管理和动态配置
    • 搜索引擎友好的 URL 结构
  2. 🗺️ 网站地图

    • 自动生成和更新
    • 多语言支持
    • 自定义样式和配置
  3. 🌍 国际化支持

    • 多语言切换
    • 路由国际化
    • SEO 多语言优化

📈 下一步计划

  1. 继续完善Layout的部分
  2. 按照功能模块完成各页面内容
  3. 优化页面加载性能
  4. 集成更多分析工具

通过本章的配置,你的 Nuxt 应用已经具备了完善的 SEO 优化、多语言支持和数据分析能力,为面向全球用户提供高质量的 Web 体验奠定了坚实基础!🎉


相关资源-