Files
gitlab-instance-0a899031_no…/components/locale-provider.tsx

76 lines
1.6 KiB
TypeScript

"use client";
import {
createContext,
useContext,
useEffect,
useMemo,
useState,
type ReactNode,
} from "react";
import { isChinaUser } from "is-china-user";
import { dictionaries, type Dictionary, type Locale } from "~/lib/i18n";
type LocaleContextValue = {
locale: Locale;
isChina: boolean;
ready: boolean;
t: Dictionary;
};
const LocaleContext = createContext<LocaleContextValue | null>(null);
export function LocaleProvider({ children }: { children: ReactNode }) {
// Default zh to match primary audience; switch after client detection.
const [locale, setLocale] = useState<Locale>("zh");
const [ready, setReady] = useState(false);
useEffect(() => {
let cancelled = false;
try {
const china = Boolean(isChinaUser());
if (!cancelled) {
setLocale(china ? "zh" : "en");
setReady(true);
}
} catch {
if (!cancelled) {
setLocale("zh");
setReady(true);
}
}
return () => {
cancelled = true;
};
}, []);
useEffect(() => {
if (!ready) return;
document.documentElement.lang = dictionaries[locale].htmlLang;
}, [locale, ready]);
const value = useMemo<LocaleContextValue>(
() => ({
locale,
isChina: locale === "zh",
ready,
t: dictionaries[locale],
}),
[locale, ready],
);
return (
<LocaleContext.Provider value={value}>{children}</LocaleContext.Provider>
);
}
export function useLocale() {
const ctx = useContext(LocaleContext);
if (!ctx) {
throw new Error("useLocale must be used within LocaleProvider");
}
return ctx;
}