Nuxt 3中如何从API获取Locales配置i18n?
动态配置Nuxt 3 i18n + Prismic CMS locales的解决方案
核心问题分析
你遇到的问题本质是:Nuxt i18n的路由规则在初始化阶段就已生成,动态修改locales后无法自动同步路由;同时defineNuxtConfig不支持异步操作,直接修改现有i18n实例无法触发布局和路由的更新。
正确实现步骤
1. 确保useLocales返回符合i18n格式的数据
先确认你的组合式函数能正确将Prismic返回的locales转换为vue-i18n所需的结构:
// composables/useLocales.ts export const useLocales = async () => { const prismicLocales = await $prismic.client.getAllLocales(); // 转换为i18n要求的格式:必须包含code字段,可选name、iso等 return prismicLocales.map(locale => ({ code: locale.id, name: locale.name, iso: locale.lang })); };
2. 基础配置Nuxt i18n(nuxt.config.ts)
关闭自动路由生成,避免初始化冲突:
// nuxt.config.ts export default defineNuxtConfig({ modules: ['@nuxtjs/i18n'], i18n: { legacy: false, globalInjection: true, defaultLocale: 'en-pl', locales: [], // 留空,后续动态注入 strategy: 'prefix_except_default', // 采用默认语言无前缀的路由策略 detectBrowserLanguage: false, // 关闭自动检测,防止初始化时的异步冲突 routesNameSeparator: '___' // 保持默认的路由命名分隔符 } });
3. 自定义插件初始化i18n并同步路由
创建plugins/i18n-dynamic.ts,在插件中异步获取locales,初始化i18n并手动生成路由规则:
// plugins/i18n-dynamic.ts import { createI18n } from 'vue-i18n'; export default defineNuxtPlugin(async (nuxtApp) => { const locales = await useLocales(); const router = useRouter(); const defaultLocale = 'en-pl'; // 初始化i18n实例 const i18n = createI18n({ legacy: false, globalInjection: true, locale: defaultLocale, locales: locales }); // 挂载到Vue应用 nuxtApp.vueApp.use(i18n); // 动态生成带locale前缀的路由 const generateLocalizedRoutes = () => { const localizedRoutes = []; // 遍历原始路由,为每个locale生成对应路由 router.options.routes.forEach(route => { // 默认语言路由(无前缀) localizedRoutes.push({ ...route, name: `${route.name}___${defaultLocale}` }); // 其他语言路由(带前缀) locales.forEach(locale => { if (locale.code !== defaultLocale) { localizedRoutes.push({ ...route, path: `/${locale.code}${route.path}`, name: `${route.name}___${locale.code}` }); } }); }); // 更新路由配置并添加到路由器 router.options.routes = localizedRoutes; localizedRoutes.forEach(route => router.addRoute(route)); }; generateLocalizedRoutes(); // 将i18n实例全局提供,方便组件调用 return { provide: { i18n: i18n.global } }; });
4. 全局存储locales(可选)
如果需要在组件中复用locales数据,可在插件中存入全局状态:
// 在插件中添加以下代码 useState('appLocales', () => locales);
为什么之前的方案失效?
- 方案1:
defineNuxtConfig是构建阶段同步执行的配置文件,不支持异步操作,无法直接调用await useLocales()。 - 方案2:仅修改
$i18n.locales只会更新i18n内部的语言列表,但Nuxt i18n的路由规则在初始化时就已固定,不会自动同步更新。 - 方案3:重新创建i18n实例会覆盖原有模块生成的实例,但未同步更新Nuxt的路由系统,导致路由规则不生效,还可能引发内部逻辑冲突。
内容的提问来源于stack exchange,提问作者Maksymilian Olszewski
相关产品推荐
相关产品推荐

