Nuxt.js 国际化配置完整教程(含版本兼容与问题解决)
一、整体配置思路
Nuxt 国际化配置的核心是通过 @nuxtjs/i18n
模块实现多语言切换,核心思路分为5步,逻辑调整如下:
- 确认环境兼容性:先明确 Nuxt 版本(2.x 还是 3.x),因为
@nuxtjs/i18n
版本与 Nuxt 版本强绑定(Nuxt 2 需用 7.x 版本,Nuxt 3 需用 8.x+)。 - 准备语言文件:在
locales
文件夹中创建多语言 JSON 文件(如zh-CN.json
、en-US.json
),统一管理文本。 - 配置 i18n 模块:在
nuxt.config.js
中注册模块并配置语言列表、默认语言、懒加载等核心参数。 - 实现语言切换功能:开发切换组件,通过
$i18n
实例方法切换语言。 - 集成与测试:将切换组件嵌入页面,验证翻译与路由切换是否正常。
二、详细配置步骤
1. 环境准备与依赖安装
关键前提:版本兼容性
- Nuxt 2.x:必须使用
@nuxtjs/i18n@7.x
(最新 7.3.1),不支持 8.x+ 版本。 - Nuxt 3.x:需使用
@nuxtjs/i18n@8.x+
(目前最新 8.0.0-rc.5)。
本文以 Nuxt 2.x 为例:
# 安装指定版本的 i18n 模块(解决版本冲突)
npm install @nuxtjs/i18n@7.3.1 --save --legacy-peer-deps
# 若依赖冲突严重,强制忽略引擎检查(谨慎使用)
npm install @nuxtjs/i18n@7.3.1 --save --legacy-peer-deps --ignore-engines
说明:
--legacy-peer-deps
用于解决 npm 7+ 对 peerDependencies 的严格检查导致的冲突;--ignore-engines
忽略 Node 版本限制(仅当明确环境兼容时使用)。
2. 创建语言文件
在项目根目录创建 locales
文件夹(注意拼写,非 locals
),存放多语言 JSON:
// locales/zh-CN.json
{
"common": {
"language": "语言",
"home": "首页",
"welcome": "欢迎使用"
},
"button": {
"submit": "提交"
}
}
// locales/en-US.json
{
"common": {
"language": "Language",
"home": "Home",
"welcome": "Welcome"
},
"button": {
"submit": "Submit"
}
}
3. 配置 nuxt.config.js
在配置文件中注册 @nuxtjs/i18n
模块并设置核心参数:
// nuxt.config.js
export default {
// 注册 i18n 模块
modules: ['@nuxtjs/i18n'],
// i18n 核心配置
i18n: {
// 语言列表(与 locales 文件夹下的文件对应)
locales: [
{
code: 'zh', // 语言标识(用于路由切换,如 /zh/home)
iso: 'zh-CN', // 国际标准格式(用于 HTML lang 属性)
name: '中文', // 语言名称(用于切换组件显示)
file: 'zh-CN.json' // 对应 locales 下的文件
},
{
code: 'en',
iso: 'en-US',
name: 'English',
file: 'en-US.json'
}
],
defaultLocale: 'zh', // 默认语言
lazy: true, // 开启懒加载(按需加载语言文件,优化性能)
langDir: 'locales/', // 语言文件存放路径
vueI18n: {
fallbackLocale: 'zh' // 当翻译缺失时,默认使用中文
},
// 可选:在 HTML 标签中添加 lang 属性(利于 SEO)
detectBrowserLanguage: {
enabled: false // 关闭自动检测浏览器语言(避免冲突)
}
}
}
4. 开发语言切换组件
创建 components/LanguageSwitcher.vue
,实现语言切换功能:
<template>
<div class="language-switcher">
<!-- 不依赖 Element UI 的基础版本 -->
<select v-model="currentLang" @change="switchLang">
<option value="zh">中文</option>
<option value="en">English</option>
</select>
<!-- 若使用 Element UI,可替换为: -->
<!-- <el-dropdown @command="switchLang">
<span class="el-dropdown-link">
{{ $t('common.language') }}
<i class="el-icon-arrow-down el-icon--right"></i>
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item command="zh">中文</el-dropdown-item>
<el-dropdown-item command="en">English</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown> -->
</div>
</template>
<script>
export default {
computed: {
// 获取当前语言(从 i18n 实例中)
currentLang() {
return this.$i18n.locale;
}
},
methods: {
// 切换语言
switchLang(lang) {
// 若使用 select 标签,lang 为 event.target.value
const targetLang = typeof lang === 'string' ? lang : lang.target.value;
// 切换语言并更新路由(如从 /home → /en/home)
this.$router.push(this.switchLocalePath(targetLang));
}
}
};
</script>
<style scoped>
.language-switcher {
margin: 10px;
}
select {
padding: 4px 8px;
border-radius: 4px;
border: 1px solid #ddd;
}
</style>
关键说明:
$i18n.locale
:获取/设置当前语言。switchLocalePath(targetLang)
:i18n 提供的路由切换方法,自动拼接语言前缀(如zh
→/home
,en
→/en/home
)。
5. 集成到页面/布局
在布局文件(如 layouts/default.vue
)或页面中引入切换组件:
// layouts/default.vue
<template>
<div>
<!-- 头部导航 -->
<header>
<LanguageSwitcher /> <!-- 引入切换组件 -->
<nav>
<a :href="switchLocalePath('zh')">{{ $t('common.home') }}</a>
</nav>
</header>
<nuxt /> <!-- 页面内容 -->
</div>
</template>
<script>
import LanguageSwitcher from '~/components/LanguageSwitcher.vue';
export default {
components: { LanguageSwitcher }
};
</script>
在页面中使用翻译文本:
// pages/index.vue
<template>
<div>
<h1>{{ $t('common.welcome') }}</h1>
<button>{{ $t('button.submit') }}</button>
</div>
</template>
三、常见问题与解决方案
1. Nuxt 2 与 i18n 版本冲突
错误表现:
- 启动时报错:
Cannot find module '@nuxtjs/i18n'
- 运行时错误:
this.$i18n is undefined
或方法不存在
原因:安装了不兼容的版本(如 Nuxt 2 用了 8.x+ 版本)。
解决:
# 卸载错误版本
npm uninstall @nuxtjs/i18n
# 安装兼容版本
npm install @nuxtjs/i18n@7.3.1 --save --legacy-peer-deps
2. 依赖冲突(peerDependencies 错误)
错误信息:
npm error peer eslint@"^5.0.0 || ^6.0.0" from eslint-plugin-vue@6.2.2
npm error Could not resolve dependency
原因:npm 7+ 对 peer 依赖的检查更严格,旧项目依赖版本不匹配。
解决:
# 安装时忽略 peer 依赖冲突
npm install --legacy-peer-deps
# 如果需长期忽略,可在 .npmrc 中添加(但是不推荐哈)
echo "legacy-peer-deps=true" >> .npmrc
3. 语言文件加载失败
错误表现:
- 翻译文本显示为
[missing "common.home" translation]
- 控制台报错:
Failed to load lang file: zh-CN.json
原因:
- 语言文件路径错误(如文件夹名拼写为
locals
而非locales
)。 nuxt.config.js
中langDir
配置错误(需与实际文件夹名一致)。
解决:
- 确保文件夹名为
locales
(复数形式)。 - 检查
i18n.langDir
配置:langDir: 'locales/'
(末尾斜杠不可少)。
4. 语言切换后路由不更新
错误表现:
- 切换语言后,URL 未添加语言前缀(如始终为
/home
,而非/en/home
)。 - 页面内容未重新渲染。
原因:未使用 switchLocalePath
方法更新路由。
解决:
- 切换语言时必须调用
this.$router.push(this.switchLocalePath(targetLang))
,而非直接修改$i18n.locale
。 - 确保
nuxt.config.js
中i18n
配置未禁用路由生成(默认启用)。
四、扩展建议
1. 语言切换持久化
通过 localStorage
保存用户选择的语言,刷新页面后保持状态:
// 在切换组件的 switchLang 方法中添加
switchLang(lang) {
const targetLang = typeof lang === 'string' ? lang : lang.target.value;
localStorage.setItem('preferredLang', targetLang); // 保存到本地
this.$router.push(this.switchLocalePath(targetLang));
}
// 在 nuxt.config.js 中初始化(通过插件)
// plugins/i18n-init.js
export default ({ app }) => {
const savedLang = localStorage.getItem('preferredLang');
if (savedLang) {
app.i18n.locale = savedLang;
}
};
// 在 nuxt.config.js 中注册插件
plugins: ['~/plugins/i18n-init.js']
2. 多语言 SEO 优化
- 在页面头部添加
hreflang
标签,告诉搜索引擎不同语言版本的对应关系:
// 在页面或布局的 head 中配置
head() {
return {
htmlAttrs: {
lang: this.$i18n.locale // 页面语言属性
},
link: [
{ rel: 'alternate', hreflang: 'zh-CN', href: `https://your-domain.com${this.switchLocalePath('zh')}` },
{ rel: 'alternate', hreflang: 'en-US', href: `https://your-domain.com${this.switchLocalePath('en')}` }
]
};
}
3. 动态内容国际化
对于 API 返回的动态内容(如商品名称),可在后端返回多语言字段,前端根据当前语言选择显示:
// API 返回示例
{
"id": 1,
"name_zh": "苹果",
"name_en": "Apple"
}
// 前端使用
{{ item[`name_${$i18n.locale}`] }}
4. 批量导入语言文件
当语言文件较多时,可通过 require.context
批量导入,避免手动配置:
// 在 nuxt.config.js 中
const locales = require.context('./locales', false, /\.json$/).keys().map(file => {
const code = file.replace(/\.json$/, '');
return { code, file };
});
// 然后在 i18n.locales 中使用 locales 数组
五、总结
Nuxt 国际化配置的核心是版本兼容和正确配置 i18n 模块:
- 务必根据 Nuxt 版本选择对应的
@nuxtjs/i18n
版本(Nuxt 2 用 7.x)。 - 语言文件存放于
locales
文件夹,通过$t('key')
调用翻译。 - 语言切换需使用
switchLocalePath
方法同步路由。 - 遇到依赖冲突时,使用
--legacy-peer-deps
解决。
通过以上步骤,可实现 Nuxt 项目的多语言支持,并优化用户体验与 SEO。一路踩坑经验😅