|
- import { cookies, headers } from "next/headers";
- import { createInstance, i18n, LanguageDetectorAsyncModule } from "i18next";
- import resourcesToBackend from "i18next-resources-to-backend";
- import { getServerSession } from "next-auth";
- import { authOptions } from "@/config/authConfig";
- import I18nClientProvider from "./I18nClientProvider";
- import universalLanguageDetect from "@unly/universal-language-detector";
-
- const FALLBACK_LANG = "zh";
- const SUPPORTED_LANGUAGES = ["zh"];
-
- export const detectLanguage = async (): Promise<string> => {
- // Logic to get language preference from cookies/headers/session
- const cookiesList = cookies();
- const cookiesObj = cookiesList
- .getAll()
- .reduce<{ [name: string]: string }>(
- (acc, cookie) => ({ ...acc, [cookie.name]: cookie.value }),
- {},
- );
- const headersList = headers();
- console.time("[i18n] detectLanguage total");
- console.time("[i18n] getServerSession");
- const session = await getServerSession(authOptions);
- console.timeEnd("[i18n] getServerSession");
- console.time("[i18n] universalLanguageDetect");
- const lang = universalLanguageDetect({
- supportedLanguages: SUPPORTED_LANGUAGES,
- fallbackLanguage: FALLBACK_LANG,
- acceptLanguageHeader: headersList.get("accept-language") || undefined,
- serverCookies: cookiesObj,
- });
- console.timeEnd("[i18n] universalLanguageDetect");
- console.timeEnd("[i18n] detectLanguage total");
- return lang;
- };
-
- const languageDetector: LanguageDetectorAsyncModule = {
- type: "languageDetector",
- detect: detectLanguage,
- async: true,
- };
-
- const initI18next = async (namespaces: string[]): Promise<i18n> => {
- const label = `[i18n] initI18next ns=${namespaces.join(",")}`;
- console.time(label);
- const i18nInstance = createInstance();
- await i18nInstance
- .use(languageDetector)
- .use(
- resourcesToBackend((language: string, namespace: string) => {
- return import(`./${language}/${namespace}.json`);
- }),
- )
- .init({
- fallbackLng: "en",
- interpolation: {
- escapeValue: false,
- },
- ns: namespaces,
- });
- return i18nInstance as i18n;
- };
-
- export const getServerI18n = async (...namespaces: string[]) => {
- return initI18next(namespaces);
- };
-
- interface Props {
- children: React.ReactNode;
- namespaces: string[];
- }
-
- // Provides the resources for the client
- export const I18nProvider: React.FC<Props> = async ({
- children,
- namespaces,
- }) => {
- const i18n = await getServerI18n(...namespaces);
- const language = i18n.language;
- const resources = namespaces.reduce<{ [ns: string]: any }>(
- (acc, ns) => ({
- ...acc,
- [ns]: i18n.getResourceBundle(language, ns),
- }),
- {},
- );
-
- return (
- <I18nClientProvider
- language={language}
- resources={resources}
- namespaces={namespaces}
- >
- {children}
- </I18nClientProvider>
- );
- };
|