[Nuxt 4 实战] 赚美刀的第一步:手把手教你实现 Nuxt 4 国际化 (i18n)

6 阅读4分钟

前言

做工具站,如果只做中文市场,不仅竞争激烈(卷),而且广告单价(RPM)相对较低。想要获得更高的被动收入,出海是必经之路。

想象一下,你的工具站支持英文后,就可以提交到 Product Hunt、Reddit 等平台,获取全球流量。

在 Nuxt 4 中,实现多语言并不是简单的“翻译文本”,它涉及到路由前缀(/en/tool)SEO 标签(hreflang)自动语言检测以及按需加载

今天这篇,我们就利用 @nuxtjs/i18n 模块,为 SonicToolLab 装上“翻译官”。

🌍 1. 安装与基础配置

Nuxt 官方推荐的国际化模块是 @nuxtjs/i18n(目前 v8/v9 版本适配 Nuxt 3/4,这里pnpm和i18n的版本不要太新)。

安装依赖

pnpm add @nuxtjs/i18n

配置文件 nuxt.config.ts

这是最关键的一步。我们需要定义支持的语言、默认语言以及路由策略。

// nuxt.config.ts
export default defineNuxtConfig({
  modules: ['@nuxtjs/i18n'],

  i18n: {
    // 策略:'prefix_except_default' 意味着默认语言(中文)不带前缀,其他语言带前缀
    // 中文:/tools/json
    // 英文:/en/tools/json
    strategy: 'prefix_except_default', 
    
    defaultLocale: 'zh', // 默认语言
    
    // 语言配置列表
    locales: [
      {
        code: 'en',
        name: 'English',
        file: 'en.json' // 翻译文件路径
      },
      {
        code: 'zh',
        name: '简体中文',
        file: 'zh.json'
      }
    ],
    
    // 懒加载:只有切换到英文时,才加载 en.json,减小首屏体积
    lazy: true,
    langDir: 'locales', // 翻译文件存放目录
    
    // 自动检测浏览器语言并重定向
    detectBrowserLanguage: {
      useCookie: true,
      cookieKey: 'i18n_redirected',
      redirectOn: 'root', // 仅在访问根目录时检测
    }
  }
})

📝 2. 管理翻译文件

在项目根目录下创建 locales 文件夹。

DX 建议: 强烈推荐在 VS Code 中安装 i18n Ally 插件,它能让你在代码里直接看到翻译后的文案,不用来回切文件。

locales/zh.json:

{
  "nav": {
    "home": "首页",
    "tools": "工具列表",
    "about": "关于我们"
  },
  "hero": {
    "title": "开发者的百宝箱",
    "subtitle": "免费、快速、隐私安全的在线工具"
  }
}

locales/en.json:

{
  "nav": {
    "home": "Home",
    "tools": "Tools",
    "about": "About"
  },
  "hero": {
    "title": "Developer's Toolkit",
    "subtitle": "Free, Fast, and Privacy-Focused Online Tools"
  }
}

🗣️ 3. 组件中的使用

文本替换

将原本写死的中文换成 $t() 函数。

<template>
  <h1>{{ $t('hero.title') }}</h1>
  <p>{{ $t('hero.subtitle') }}</p>
</template>

链接跳转 (关键!)

千万不要直接写 to="/tools"。 如果在英文版页面点击这个链接,会跳回中文版。必须使用 useLocalePath

<script setup>
const localePath = useLocalePath()
</script>

<template>
  <NuxtLink :to="localePath('tools')">
    {{ $t('nav.tools') }}
  </NuxtLink>
</template>

🔄 4. 制作语言切换器

我们需要一个下拉菜单或按钮来切换语言。这里用 Nuxt UI 的 UDropdownUSelectMenu 实现。

<script setup>
const { locale, locales, setLocale } = useI18n()

// 计算当前语言的名称
const currentLocale = computed(() => {
  return locales.value.find(i => i.code === locale.value)
})

// 切换语言函数
const onLocaleChanged = (code) => {
  setLocale(code)
}
</script>

<template>
  <div class="flex items-center gap-2">
    <UButton 
      color="gray" 
      variant="ghost"
      @click="onLocaleChanged(locale === 'zh' ? 'en' : 'zh')"
    >
      {{ locale === 'zh' ? 'En' : '中' }}
    </UButton>
  </div>
</template>

🕷️ 5. SEO 与 Hreflang (重中之重)

做了多语言,如果 Google 认为你的中文页和英文页是“重复内容”,那就麻烦了。

好消息是,@nuxtjs/i18n 模块会自动为每个页面生成 <link rel="alternate" hreflang="..." /> 标签。

检查方法: 打开网页源代码,查看 <head> 部分,你应该能看到类似的代码:

<link rel="alternate" href="[https://sonictoollab.dpdns.org/](https://sonictoollab.dpdns.org/)" hreflang="zh" />
<link rel="alternate" href="[https://sonictoollab.dpdns.org/en](https://sonictoollab.dpdns.org/en)" hreflang="en" />
<link rel="alternate" href="[https://sonictoollab.dpdns.org/](https://sonictoollab.dpdns.org/)" hreflang="x-default" />

这告诉 Google:“如果用户说中文,给他看这个;如果用户说英文,给他看那个。”这是多语言 SEO 排名的基石。

注意: 务必在 nuxt.config.ts 中配置 site.url (配合 @nuxtjs/seo) 或 i18n.baseUrl,否则生成的链接可能不带域名。

⚠️ 6. 避坑指南:Hydration Mismatch

在服务端渲染(SSR)中,如果不小心处理,很容易出现“服务端渲染了中文,客户端检测到浏览器是英文,强行变成了英文”,导致页面闪烁或控制台报错。

最佳实践:

  1. 依赖路由前缀: 尽量让 URL 决定语言(/en),而不是单纯依赖 Cookie。
  2. Date/Number 格式化: 如果你在页面上显示日期,不要用 JS 原生的 new Date().toLocaleDateString(),因为它依赖运行环境。请使用 i18n 提供的 $d() 函数,确保服务端和客户端输出一致。
<p>{{ $d(new Date(), 'short') }}</p>

总结

通过配置 i18n,SonicToolLab 成功具备了接待全球用户的能力。

虽然前期的翻译工作比较繁琐(特别是工具的说明文案),但这是一次性的投入。一旦部署完成,你的工具站市场规模将从 14 亿人瞬间扩展到 80 亿人。

至此,我们的 Nuxt 4 技术实战系列专栏就告一段落了。

从环境搭建、部署运维、功能开发、性能优化、SEO、UI细节到今天的国际化,我们完整走完了一个独立开发者打造产品的全过程。

希望这个系列能成为你开发路上的一盏路灯。如果你也做出了自己的产品,别忘了发给我看看!

👉 SonicToolLab 在线体验