Next.js中无SSG/SSR时如何在组件中使用next-i18next?
问题解析与解决方案
核心原因
你的不可运行代码失效,是因为next-i18next的useTranslation默认依赖页面级预加载的翻译资源——只有通过serverSideTranslations(配合SSG/SSR的getStaticProps/getServerSideProps)把翻译资源注入页面后,组件才能拿到对应的翻译内容。非页面组件(如NavBar、Footer)如果没有上层页面提供翻译资源,直接调用useTranslation会找不到对应key的翻译,最终返回key本身。
不依赖SSG/SSR的组件翻译方案
下面提供三种无需在组件或页面单独写SSG/SSR逻辑的实现方式:
方案1:独立初始化客户端i18next实例
脱离next-i18next的服务端预加载逻辑,直接在客户端初始化i18next,让组件可以独立获取翻译:
- 创建
i18n.js配置文件:
import i18n from 'i18next'; import { initReactI18next } from 'react-i18next'; import LanguageDetector from 'i18next-browser-languagedetector'; // 导入对应语言的翻译文件 import translationEN from '../public/locales/en/common.json'; import translationZH from '../public/locales/zh/common.json'; import translationFooterEN from '../public/locales/en/footer.json'; import translationFooterZH from '../public/locales/zh/footer.json'; const resources = { en: { common: translationEN, footer: translationFooterEN }, zh: { common: translationZH, footer: translationFooterZH } }; i18n .use(LanguageDetector) // 自动检测浏览器语言 .use(initReactI18next) .init({ resources, fallbackLng: 'en', interpolation: { escapeValue: false // React已处理XSS,无需转义 } }); export default i18n;
- 在
_app.js中全局导入配置:
import '../i18n'; import { AppProps } from 'next/app'; function MyApp({ Component, pageProps }) { return <Component {...pageProps} />; } export default MyApp;
之后你的Footer组件就可以直接使用useTranslation,无需任何SSG/SSR逻辑:
import { useTranslation } from 'react-i18next'; export const Footer = () => { const { t } = useTranslation('footer'); return ( <footer> <p>{t('description')}</p> </footer> ) }
方案2:在_app.js全局注入翻译资源
如果仍想保留next-i18next的配置体系,可在全局_app.js中统一预加载翻译资源,所有子组件共享:
import { appWithTranslation } from 'next-i18next'; import { serverSideTranslations } from 'next-i18next/serverSideTranslations'; import type { AppProps } from 'next/app'; function MyApp({ Component, pageProps }: AppProps) { return <Component {...pageProps} />; } // 在_app的getStaticProps中全局预加载所有需要的翻译文件 export async function getStaticProps({ locale }) { return { props: { ...(await serverSideTranslations(locale, ['common', 'footer'])), }, }; } export default appWithTranslation(MyApp);
此时所有子组件(包括Footer、NavBar)都能直接使用useTranslation,无需自己添加SSG/SSR逻辑。
方案3:组件内动态加载翻译资源
如果不想预加载所有翻译文件,可在组件内根据当前语言动态加载对应资源:
import { useTranslation } from 'react-i18next'; import { useEffect } from 'react'; export const Footer = () => { const { t, i18n: instance } = useTranslation('footer'); // 动态加载对应语言的翻译文件 const loadTranslations = async () => { if (!instance.hasResourceBundle(instance.language, 'footer')) { const translations = await import(`../public/locales/${instance.language}/footer.json`); instance.addResourceBundle(instance.language, 'footer', translations.default); } }; // 语言切换或组件挂载时加载 useEffect(() => { loadTranslations(); }, [instance.language]); return ( <footer> <p>{t('description')}</p> </footer> ) }
注意:这种方式会有翻译加载延迟,建议配合loading状态优化用户体验。
内容的提问来源于stack exchange,提问作者next951595
相关产品推荐
相关产品推荐

