Nuxt 4 国际化(i18n)完整配置：从基础设置到高级优化

h1Nuxt4国际化(i18n)完整配置：从基础设置到高级优化p本文档基于 code@nuxtjs/i18n 模块，版本为10.2.1，详细讲解在 Nuxt 4 项目中实现国际化的完整流程，并特别指出中文配置中的常见“痛点”及解决方案。blockquotep⚠️ 重要提示：@nuxtjs/i18n v10 版本相对于 v8 有重大重构，配置方式、API 和路由策略均发生了较大变化。如果你之前使用过旧版本，请务必抛弃固有认知，以本文档和官方文档为准，避免因版本差异导致的配置错误。hrdetailssummary适用版本ulliNuxt: strongv4liNuxt i18n: strongV10blockquotep如果你用的是其他版本，核心思路可参考，但具体 API 可能需要调整。hrh2一、快速开始h31.1 安装模块precodespanspanpnpmspan installspan @nuxt/i18n h31.2 基础配置 (codenuxt.config.ts)precodespanspanexportspan defaultspan defineNuxtConfigspan(span{ spanspan modulesspan:span [span"span@nuxtjs/i18nspan"span]span, spanspan spanspan i18nspan:span { spanspan // 语言环境配置（核心） spanspan localesspan:span [ spanspan { spanspan codespan:span "spanzh_cnspan"span,span // 程序内部标识符（URL路径使用） spanspan namespan:span "span简体中文span"span,span // 显示名称 spanspan languagespan:span "spanzh-CNspan"span,span // 用于HTML lang属性的标准语言标签 spanspan filespan:span "spanzh_cn.jsonspan"span,span // 对应的语言文件 spanspan }, spanspan { spanspan codespan:span "spanenspan"span, spanspan namespan:span "spanEnglishspan"span, spanspan languagespan:span "spanen-USspan"span, spanspan filespan:span "spanen-US.jsonspan"span, spanspan }, spanspan { spanspan codespan:span "spanjaspan"span, spanspan namespan:span "span日本語span"span, spanspan languagespan:span "spanja-JPspan"span, spanspan filespan:span "spanja-JP.jsonspan"span, spanspan }, spanspan ]span, spanspan spanspan // 默认语言设置（必须与某个code完全匹配） spanspan defaultLocalespan:span "spanzh_cnspan"span, spanspan spanspan // 语言文件目录 spanspan langDirspan:span "spanlocalesspan"span, spanspan spanspan // 路由策略 spanspan strategyspan:span "spanprefix_except_defaultspan"span,span // 推荐：默认语言无前缀 spanspan spanspan // 浏览器语言检测 spanspan detectBrowserLanguagespan:span { spanspan useCookiespan:span truespan, spanspan cookieKeyspan:span "spani18n_redirectedspan"span, spanspan redirectOnspan:span "spanrootspan"span, spanspan }, spanspan }, spanspan}span)span; h31.3 语言文件结构p创建语言文件目录和文件：precodeproject-root/ ├── i18n/ │ └── locales/ │ ├── zh_cn.json # 简体中文 │ ├── en.json # 英文 │ └── ja.json # 日文 ├── nuxt.config.ts └── app.vue h31.4 创建语言文件pstrongcodelocales/zh_cn.json:precodespanspan{ spanspan "spanwelcomespan"span:span "span欢迎使用我们的应用span"span, spanspan "spanaboutspan"span:span "span关于我们span"span, spanspan "spanuserspan"span:span { spanspan "spanprofilespan"span:span "span用户资料span"span, spanspan "spansettingsspan"span:span "span设置span" spanspan } spanspan} pstrongcodelocales/en.json:precodespanspan{ spanspan "spanwelcomespan"span:span "spanWelcome to our appspan"span, spanspan "spanaboutspan"span:span "spanAbout Usspan"span, spanspan "spanuserspan"span:span { spanspan "spanprofilespan"span:span "spanUser Profilespan"span, spanspan "spansettingsspan"span:span "spanSettingsspan" spanspan } spanspan} pstronglocales/ja.jsonprecodespanspan{ spanspan "spanwelcomespan"span:span "spanアプリへようこそspan"span, spanspan "spanaboutspan"span:span "span会社概要span"span, spanspan "spanuserspan"span:span { spanspan "spanprofilespan"span:span "spanユーザープロフィールspan"span, spanspan "spansettingsspan"span:span "span設定span" spanspan } spanspan} h31.5 动态区域设置precodespanspan spanspanimportspan *span asspan locales spanfromspan "span@nuxt/ui/localespan"span; spanspan spanspanconstspan {span locale span}span =span useI18nspan()span; spanspan spanspan spanspan spanspan spanspan spanspan spanspan h31.6 动态方向设置precodespanspan spanspanimportspan *span asspan locales spanfromspan "span@nuxt/ui/localespan"span; spanspan spanspanconstspan {span locale span}span =span useI18nspan()span; spanspan spanspanconstspan lang span=span computedspan(span()span =>span locales[localespan.spanvalue]span.spancode)span; spanspanconstspan dir span=span computedspan(span()span =>span locales[localespan.spanvalue]span.spandir)span; spanspan spanspanuseHeadspan(span{ spanspan htmlAttrsspan:span { spanspan langspan, spanspan dirspan, spanspan }, spanspan}span)span; spanspan spanspan spanspan spanspan spanspan spanspan spanspan h2二、中文配置的特别痛点与解决方案h33.1 痛点一：语言标识符不一致pstrong问题：中文有多种标识符格式（codezh、codezh-CN、codezh_CN、codezh_cn），容易混淆。pstrong解决方案：ullistrongcodecode字段：用于URL路径和程序内部标识，推荐使用 strongcodezh_cn（全小写下划线）precodespanspan{span codespan:span 'spanzh_cnspan'span,span namespan:span 'span简体中文span'span } pstrongcodelanguage字段：用于HTML codelang属性和SEO，使用标准 strongcodezh-CN（连字符格式）precodespanspan{span codespan:span 'spanzh_cnspan'span,span languagespan:span 'spanzh-CNspan'span } pstrongcodedefaultLocale：必须与 codecode 值strong完全一致precodespanspandefaultLocalespan:span "spanzh_cnspan"span;span // 正确 spanspandefaultLocalespan:span "spanzh-CNspan"span;span // 错误！会导致配置不匹配 h33.2 痛点二：默认语言配置错误pstrong问题：codedefaultLocale 设置错误导致只有中文页面报错。pstrong解决方案：ollistrong严格匹配：确保 codedefaultLocale 值与中文配置的 codecode 值strong一字不差listrong配置验证：precodespanspan// 正确的完整示例 spanspanlocalesspan:span [ spanspan {span codespan:span 'spanzh_cnspan'span,span languagespan:span 'spanzh-CNspan'span,span filespan:span 'spanzh_cn.jsonspan'span } spanspan]span, spanspandefaultLocalespan:span 'spanzh_cnspan'span,span // 必须与上面的code完全相同 spanspanstrategyspan:span 'spanprefix_except_defaultspan' h33.3 痛点三：语言文件加载失败pstrong问题：控制台报错 codeCannot find module './locales/zh.json'。pstrong解决方案：ollistrong检查文件路径：确认 codelangDir 配置正确listrong验证JSON格式：语言文件必须是strong严格有效的JSONprecodespanspan// 正确 spanspan{span "spanwelcomespan"span:span "span欢迎span"span } spanspan spanspan// 错误（有注释） spanspan{ spanspan // 欢迎语 spanspan "spanwelcomespan"span:span "span欢迎span" spanspan} spanspan spanspan// 错误（有尾随逗号） spanspan{span "spanwelcomespan"span:span "span欢迎span"span,span } h2四、高级配置h34.1 子域名国际化（像Vue官网一样）precodespanspani18nspan:span { spanspan localesspan:span [ spanspan { spanspan codespan:span 'spanzh_cnspan'span, spanspan domainspan:span 'spancn.your-app.comspan'span,span // 生产环境子域名 spanspan languagespan:span 'spanzh-CNspan'span, spanspan filespan:span 'spanzh_cn.jsonspan' spanspan }, spanspan { spanspan codespan:span 'spanenspan'span, spanspan domainspan:span 'spanyour-app.comspan'span,span // 主域名作为默认语言 spanspan languagespan:span 'spanen-USspan'span, spanspan filespan:span 'spanen.jsonspan' spanspan } spanspan ]span, spanspan differentDomainsspan:span truespan,span // 启用子域名模式 spanspan defaultLocalespan:span 'spanenspan'span,span // 默认语言对应主域名 spanspan detectBrowserLanguagespan:span falsespan // 子域名模式下通常禁用 spanspan} stylehtml pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}