Article
🎯 概述
在现代 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">// 基础页面 SEOuseHead({ 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} - 游戏讨论&创作社区` : '游戏讨论&创作社区 - 玩家的精神家园' }})
// 根据路由动态设置 SEOconst 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 // 不包含在网站地图中})
// 或者使用 useSeoMetauseSeoMeta({ 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. 创建动态路由网站地图
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/ 目录并添加语言文件-
{ "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": "作品展示" }}{ "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. 语言切换组件
<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. 自定义路由名称
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
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 图片组件
<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 优化、网站地图生成和国际化配置的完整实现方案-
✅ 完成的功能
-
🔍 SEO 优化
- 元数据管理和动态配置
- 搜索引擎友好的 URL 结构
-
🗺️ 网站地图
- 自动生成和更新
- 多语言支持
- 自定义样式和配置
-
🌍 国际化支持
- 多语言切换
- 路由国际化
- SEO 多语言优化
📈 下一步计划
- 继续完善Layout的部分
- 按照功能模块完成各页面内容
- 优化页面加载性能
- 集成更多分析工具
通过本章的配置,你的 Nuxt 应用已经具备了完善的 SEO 优化、多语言支持和数据分析能力,为面向全球用户提供高质量的 Web 体验奠定了坚实基础!🎉
相关资源-