Files
calendar/packages/lib/hooks/useLocale.ts
T
Benny JooandGitHub b17b5a169f perf: make useLocale hook to use server-fetched i18n if in App router context (#20597)
* write I18nProvider

* rename

* update useLocale

* fix

* use a singleton

* safer

* better

* fix e2e test 1

* fix e2e test 2

* fix e2e test 3

* fix e2e test 4

* fix

* refactor

* address comments

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix

* fix flaky test

* add more caching

* revert changes to e2e tests

* add jsdoc

* memoize

* update window object with new translations in /settings/my-account/general

* remove dead code

* only use locale and ns as deps

* fix
2025-04-11 14:28:26 -07:00

72 lines
1.9 KiB
TypeScript

import { createInstance } from "i18next";
import type { TFunction, i18n } from "i18next";
import { useContext } from "react";
import { useTranslation } from "react-i18next";
import { useAtomsContext } from "@calcom/atoms/hooks/useAtomsContext";
import { AppRouterI18nContext } from "@calcom/web/app/AppRouterI18nProvider";
type useLocaleReturnType = {
i18n: i18n;
t: TFunction;
isLocaleReady: boolean;
};
// @internal
const useClientLocale = (namespace: Parameters<typeof useTranslation>[0] = "common"): useLocaleReturnType => {
const context = useAtomsContext();
const { i18n, t } = useTranslation(namespace);
const isLocaleReady = Object.keys(i18n).length > 0;
if (context?.clientId) {
return { i18n: context.i18n, t: context.t, isLocaleReady: true } as unknown as useLocaleReturnType;
}
return {
i18n,
t,
isLocaleReady,
};
};
// @internal
const serverI18nInstances = new Map();
export const useLocale = (): useLocaleReturnType => {
const appRouterContext = useContext(AppRouterI18nContext);
const clientI18n = useClientLocale();
if (appRouterContext) {
const { translations, locale, ns } = appRouterContext;
const instanceKey = `${locale}-${ns}`;
// Check if we already have an instance for this locale and namespace
if (!serverI18nInstances.has(instanceKey)) {
const i18n = createInstance();
i18n.init({
lng: locale,
resources: {
[locale]: {
[ns]: translations,
},
},
});
serverI18nInstances.set(instanceKey, {
t: i18n.getFixedT(locale, ns),
isLocaleReady: true,
i18n,
});
}
return serverI18nInstances.get(instanceKey);
}
console.warn(
"useLocale hook is being used outside of App Router - hence this hook will use a global, client-side i18n which can cause a small flicker"
);
return {
t: clientI18n.t,
isLocaleReady: clientI18n.isLocaleReady,
i18n: clientI18n.i18n,
};
};