You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Nuxt 3中配置异步i18n?客户端翻译丢失问题

Nuxt 3 异步i18n客户端翻译丢失问题解决

问题背景

需要实现Nuxt 3异步i18n配置:从API获取可用语言→通过路由前缀/Cookie检测当前语言并加载对应翻译→监听onBeforeLanguageSwitch事件按需加载新语言翻译。当前遇到的问题是:服务端渲染正常,HTML中可见翻译内容,但客户端侧i18n会重新初始化,导致翻译数据丢失。

现有代码

nuxt.config.ts

i18n: {
    locales: ['en', 'ru', 'es', 'de', 'fi', 'sv', 'fr', 'it', 'br'],
    defaultLocale: 'en',
    strategy: 'prefix',
    detectBrowserLanguage: {
      useCookie: true,
      cookieKey: 'i18n_redirected',
      redirectOn: 'root',
    },
  },

plugins/i18n.ts

export default defineNuxtPlugin(nuxtApp => {

  useAsyncData('directory_translations', async () => {
    const data = await DirectoryApi.getAllDirectories()
    const directory = DirectoryService.createDirectoryObject(data)
    const translationsData = await DirectoryApi.getTranslations(directory.languages[nuxtApp.$i18n.locale.value].ID)
    const translations = DirectoryService.createTranslationsObject(translationsData, directory)

    nuxtApp.$i18n.mergeLocaleMessage(nuxtApp.$i18n.locale.value, translations)
    useState('directory', () => directory)
    useState('translations', () => translations)

  })

  nuxtApp.$i18n.onBeforeLanguageSwitch = async (oldLocale, newLocale, isInitialSetup, nuxtApp) => {
    const directory = useState('directory') as Ref<Directory>
    const translationsData = await DirectoryApi.getTranslations(directory.value.languages[newLocale].ID)
    const translations = DirectoryService.createTranslationsObject(translationsData, directory.value)
    nuxtApp.$i18n.mergeLocaleMessage(newLocale, translations)
  }
})

测试组件

<script lang="ts" setup>
const {messages} = useI18n()
</script>

<template>
  <div>
    {{ JSON.stringify(messages) }}
  </div>
</template>

解决方案

问题根源

服务端通过mergeLocaleMessage添加的翻译数据,没有被序列化传递到客户端;客户端hydration时i18n重新初始化,messages恢复为空,且未从服务端传递的状态中恢复翻译数据。同时原配置硬编码了locales,不符合“从API获取可用语言”的需求。

修正步骤

1. 调整nuxt.config.ts配置

移除硬编码的locales,改为后续在插件中动态设置:

// nuxt.config.ts
i18n: {
  defaultLocale: 'en',
  strategy: 'prefix',
  detectBrowserLanguage: {
    useCookie: true,
    cookieKey: 'i18n_redirected',
    redirectOn: 'root',
  },
  locales: [] // 留空,后续动态配置
},

2. 重写plugins/i18n.ts逻辑

确保服务端获取的翻译数据能在客户端复用,同时动态设置可用语言:

// plugins/i18n.ts
export default defineNuxtPlugin(async (nuxtApp) => {
  // 1. 获取可用语言列表并动态配置i18n locales
  const { data: directory } = await useAsyncData('directory', async () => {
    const data = await DirectoryApi.getAllDirectories()
    return DirectoryService.createDirectoryObject(data)
  })

  if (directory.value) {
    nuxtApp.$i18n.locales = Object.keys(directory.value.languages).map(lang => ({
      code: lang,
      name: lang // 可根据API返回替换为语言名称
    }))
  }

  // 2. 获取当前语言翻译,客户端复用服务端数据
  const currentLocale = nuxtApp.$i18n.locale.value
  const { data: translations } = await useAsyncData(`translations_${currentLocale}`, async () => {
    if (!directory.value) return {}
    const translationsData = await DirectoryApi.getTranslations(directory.value.languages[currentLocale].ID)
    return DirectoryService.createTranslationsObject(translationsData, directory.value)
  })

  // 服务端/客户端都执行merge,保证翻译数据不丢失
  if (translations.value) {
    nuxtApp.$i18n.mergeLocaleMessage(currentLocale, translations.value)
  }

  // 3. 语言切换时按需加载翻译,避免重复请求
  nuxtApp.$i18n.onBeforeLanguageSwitch = async (oldLocale, newLocale) => {
    if (!directory.value) return
    // 检查目标语言翻译是否已加载
    if (!nuxtApp.$i18n.messages[newLocale]) {
      const translationsData = await DirectoryApi.getTranslations(directory.value.languages[newLocale].ID)
      const newTranslations = DirectoryService.createTranslationsObject(translationsData, directory.value)
      nuxtApp.$i18n.mergeLocaleMessage(newLocale, newTranslations)
    }
  }
})

3. 组件使用说明

组件无需修改,直接使用useI18n提供的t函数或messages即可:

<script lang="ts" setup>
const { t, messages } = useI18n()
</script>

<template>
  <div>
    {{ t('your.translation.key') }}
    <!-- 调试用:{{ JSON.stringify(messages) }} -->
  </div>
</template>

核心优化点

  • 用useAsyncData存储目录和翻译数据,Nuxt自动序列化并传递到客户端,避免重复API请求
  • 动态设置nuxtApp.$i18n.locales,满足从API获取可用语言的需求
  • 语言切换前检查翻译是否已存在,避免重复请求
  • 服务端和客户端都执行mergeLocaleMessage,确保客户端hydration后翻译数据正常

内容的提问来源于stack exchange,提问作者frezzzen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 14:45:33