 |
|
8
ahhtree Nov 15, 2023
layout:
<code> export async function generateStaticParams() { return Languages.map((lang) => ({ lang })); }
export default async function RootLayout({ children, params: { lang }, }: { children: React.ReactNode; params: { lang: LanguageType }; }) { return ( <html lang={lang.includes("zh") ? "zh-CN" : "en-US"}> <body className={inter.className}> <main className="relative w-full h-screen flex flex-col"> <Header lang={lang} /> {/* <ContentWrapper childNodes={children} lang={lang} /> */} <div className="relative grow w-full flex flex-col items-center justify-center"> {children} </div> <Toaster /> <Footer lang={lang} /> </main> <InitRDKit /> </body> </html> ); } </code>
settings:
<code> export type LanguageType = "en" | "zh"; export const FallbackLng: LanguageType = "en"; export const Languages: LanguageType[] = [FallbackLng, "zh"]; export const CookieLocaleName = "i18next"; export const defaultNS = "home";
export function getOptions(lng: LanguageType = FallbackLng, ns = defaultNS) { return { debug: process.env.NODE_ENV === "development", supportedLngs: Languages, fallbackLng: FallbackLng, lng, fallbackNS: defaultNS, defaultNS, ns, }; } </code>
i18n 服务端配置:
<code> const initI18next = async (lng: LanguageType, ns: string) => { const i18nInstance = createInstance({}); await i18nInstance .use(initReactI18next) .use( resourcesToBackend( (language: string, namespace: string) => import(`./locales/${language}/${namespace}.json`) ) ) .init({ ...getOptions(lng, ns), detection: { order: ["path", "htmlTag", "navigator"], // lookupCookies: "", cookieOptions: { sameSite: "lax", path: `/${lng}`, }, lookupCookie: CookieLocaleName, caches: ["localStorage"], excludeCacheFor: ["cookie"], }, }); return i18nInstance; };
export async function serverTranslation( lng: LanguageType, ns: string, options = {} ) { const i18nextInstance = await initI18next(lng, ns); return { t: i18nextInstance.getFixedT(lng, Array.isArray(ns) ? ns[0] : ns), i18n: i18nextInstance, }; }
</code>
i18n 客户端 配置:
<code> const runsOnServerSide = typeof window === "undefined";
const languageDetector = new LanguageDetector(); languageDetector.init({ useCookies: false });
// i18next .use(initReactI18next) .use(languageDetector) .use( resourcesToBackend( (language: string, namespace: string) => import(`./locales/${language}/${namespace}.json`) ) ) .init({ ...getOptions(), lng: undefined, // let detect the language on client side preload: runsOnServerSide ? Languages : [], detection: { order: ["path", "htmlTag", "navigator"], // lookupCookies: "", cookieOptions: { sameSite: "lax", }, caches: ['localStorage'], }, });
export function useTranslation( lng: string, ns: string, options?: UseTranslationOptions<any> ) { const [done, setDone] = useState(false); const [cookies, setCookie] = useCookies([CookieLocaleName]); const ret = useTranslationOrg(ns, options); const { i18n } = ret; if (runsOnServerSide && lng && i18n.resolvedLanguage !== lng) { i18n.changeLanguage(lng); } else { // debugger // eslint-disable-next-line react-hooks/rules-of-hooks const [activeLng, setActiveLng] = useState(i18n.resolvedLanguage);
// eslint-disable-next-line react-hooks/rules-of-hooks useEffect(() => { if (activeLng !== lng) { setActiveLng(lng); i18n.changeLanguage(lng); } }, [activeLng, lng, i18n]);
// eslint-disable-next-line react-hooks/rules-of-hooks useEffect(() => { if (cookies[CookieLocaleName] === lng) return; setCookie(CookieLocaleName, lng, { sameSite: "lax", path: `/${lng}` }); }, [lng, cookies, setCookie]);
useEffect(() => { setDone(true); }, []); } return ret; }
</code>
|