🎯 概述
在现代 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 优化、网站地图生成和国际化配置的完整实现方案-
✅ 完成的功能
-
🔍 SEO 优化
- 元数据管理和动态配置
- 搜索引擎友好的 URL 结构
-
🗺️ 网站地图
- 自动生成和更新
- 多语言支持
- 自定义样式和配置
-
🌍 国际化支持
- 多语言切换
- 路由国际化
- SEO 多语言优化
📈 下一步计划
- 继续完善Layout的部分
- 按照功能模块完成各页面内容
- 优化页面加载性能
- 集成更多分析工具
通过本章的配置,你的 Nuxt 应用已经具备了完善的 SEO 优化、多语言支持和数据分析能力,为面向全球用户提供高质量的 Web 体验奠定了坚实基础!🎉
相关资源-