如何在React组件外部使用next-intl?
在React组件外部使用next-intl的方案
next-intl没有像i18next那样的全局t函数,但可以通过以下方式在组件外部创建独立的翻译实例,无需每次从组件传递t:
1. 服务器端场景(如API路由、服务器组件外部函数)
利用createTranslator或createI18nServer结合getMessages生成翻译实例,步骤如下:
步骤1:创建翻译实例工具函数
// src/utils/i18n.ts import { createTranslator } from 'next-intl'; import { getMessages } from 'next-intl/server'; // 根据locale生成服务器端翻译实例 export async function getServerTranslator(locale: string) { const messages = await getMessages({ locale }); return createTranslator({ locale, messages }); }
步骤2:在外部函数中使用
// src/utils/formatFoo.ts import { getServerTranslator } from './i18n'; export async function formatFoo(foo: string, locale: string) { const t = await getServerTranslator(locale); if (foo === 'bar') { return t('bar'); } return t('default_content'); }
步骤3:在服务器组件中调用
// app/[locale]/page.tsx export default async function Page({ params: { locale } }) { const formattedText = await formatFoo('bar', locale); return <div>{formattedText}</div>; }
2. 客户端场景(如客户端工具函数、非组件逻辑)
客户端需要先获取当前的locale和messages,再通过createTranslator或createI18nClient生成实例,可结合状态管理确保实例随语言切换更新:
步骤1:用状态管理保存翻译实例
// src/store/i18nStore.ts import { create } from 'zustand'; import { createI18nClient } from 'next-intl/client'; import type { I18nClient } from 'next-intl/client'; type I18nStore = { i18n: I18nClient | null; setI18n: (locale: string, messages: Record<string, string>) => void; }; export const useI18nStore = create<I18nStore>((set) => ({ i18n: null, setI18n: (locale, messages) => { const i18n = createI18nClient({ locale, messages }); set({ i18n }); } }));
步骤2:在客户端组件中初始化实例
// app/layout.tsx(客户端组件) 'use client'; import { useLocale, useMessages } from 'next-intl/client'; import { useI18nStore } from '../store/i18nStore'; import { useEffect } from 'react'; export default function ClientLayout({ children }) { const locale = useLocale(); const messages = useMessages(); const { setI18n } = useI18nStore(); useEffect(() => { setI18n(locale, messages); }, [locale, messages, setI18n]); return <>{children}</>; }
步骤3:在外部函数中调用
// src/utils/formatFoo.ts import { useI18nStore } from '../store/i18nStore'; export function formatFoo(foo: string) { const { i18n } = useI18nStore.getState(); if (!i18n) throw new Error('翻译实例未初始化,请确保客户端组件已完成初始化'); const t = i18n.translate; if (foo === 'bar') { return t('bar'); } return t('default_content'); }
注意事项
- 服务器端需确保
locale从请求参数或路由中获取,避免硬编码; - 客户端需处理翻译实例未初始化的异常情况,可添加默认值或加载状态;
- next-intl更推荐显式管理翻译实例,避免全局状态导致的SSR hydration问题。
内容的提问来源于stack exchange,提问作者Maxime Lechevallier
相关产品推荐
相关产品推荐

