Next.js 14中使用react-i18next Trans组件无需"use client"的方法
解决Next.js 14 SSR下使用Trans组件需加"use client"的问题
问题根源
Trans组件依赖react-i18next的客户端上下文,所以必须标记为客户端组件,但这不代表整个页面要放弃SSR——你可以通过以下几种方式保持页面整体的SSR渲染:
方案1:抽离独立的客户端Trans组件
把需要用Trans的部分单独封装成一个带"use client"的组件,页面本身作为服务器组件导入它即可。页面整体仍为SSR,仅Trans组件部分在客户端做hydrate。
示例代码:
- 新建
ClientTrans.tsx:
'use client'; import { Trans } from 'react-i18next'; export default function ClientTrans({ i18nKey, ...props }: { i18nKey: string; [key: string]: any }) { return <Trans i18nKey={i18nKey} {...props} />; }
- 在你的SSR页面中使用:
// 页面组件,无"use client",保持SSR import ClientTrans from './ClientTrans'; import { serverSideTranslations } from 'next-i18next/serverSideTranslations'; export async function getStaticProps({ locale }: { locale: string }) { return { props: { ...await serverSideTranslations(locale, ['common']), }, }; } export default function Home() { return ( <div> <h1>SSR渲染的页面标题</h1> <ClientTrans i18nKey="welcome.message" /> </div> ); }
方案2:用t函数结合dangerouslySetInnerHTML替代Trans
如果你的翻译内容是完全可信的(比如自己维护的翻译文件,没有用户输入内容),可以直接用t函数获取带HTML的翻译字符串,再通过dangerouslySetInnerHTML渲染,全程不需要客户端组件。
示例:
翻译文件(en.json):
{ "welcome": { "message": "Welcome to our <strong>awesome site</strong>" } }
页面组件:
import { useTranslation } from 'react-i18next'; import { serverSideTranslations } from 'next-i18next/serverSideTranslations'; export async function getStaticProps({ locale }: { locale: string }) { return { props: { ...await serverSideTranslations(locale, ['common']), }, }; } export default function Home() { const { t } = useTranslation('common'); return ( <div> <h1>{t('welcome.title')}</h1> <div dangerouslySetInnerHTML={{ __html: t('welcome.message') }} /> </div> ); }
注意:仅在完全信任翻译内容时使用,避免XSS攻击风险。
方案3:用t函数的React元素插值替代Trans
react-i18next支持在t函数中传入React元素作为插值参数,这种方式安全无XSS风险,且完全兼容SSR,不需要使用Trans组件。
示例:
翻译文件:
{ "welcome": { "message": "Welcome to our {{siteName}}" } }
页面组件:
import { useTranslation } from 'react-i18next'; import { serverSideTranslations } from 'next-i18next/serverSideTranslations'; export async function getStaticProps({ locale }: { locale: string }) { return { props: { ...await serverSideTranslations(locale, ['common']), }, }; } export default function Home() { const { t } = useTranslation('common'); return ( <div> <h1>{t('welcome.title')}</h1> {t('welcome.message', { siteName: <strong>awesome site</strong> })} </div> ); }
内容的提问来源于stack exchange,提问作者ASG
相关产品推荐
相关产品推荐

