"use client"; import { createContext, useContext, useSyncExternalStore, type ReactNode, } from "react"; import { syncPreferredLanguage } from "@/i18n"; const I18nHydrationContext = createContext(false); const hydrationListeners = new Set<() => void>(); let hydrationReady = false; let hydrationSyncPromise: Promise | null = null; function ensurePreferredLanguageSynced(): void { if (hydrationSyncPromise) return; hydrationSyncPromise = syncPreferredLanguage() .catch(() => undefined) .then(() => { hydrationReady = true; hydrationListeners.forEach((listener) => listener()); }); } function subscribeI18nHydration(onStoreChange: () => void): () => void { hydrationListeners.add(onStoreChange); ensurePreferredLanguageSynced(); return () => hydrationListeners.delete(onStoreChange); } function getI18nHydratedSnapshot(): boolean { return hydrationReady; } function getI18nHydratedServerSnapshot(): boolean { return false; } /** hydration 完成前保持 DEFAULT_LANGUAGE,与 SSR 一致;完成后再同步用户偏好语言。 */ export function I18nHydrationProvider({ children }: { children: ReactNode }) { const hydrated = useSyncExternalStore( subscribeI18nHydration, getI18nHydratedSnapshot, getI18nHydratedServerSnapshot, ); return ( {children} ); } export function useI18nHydrated(): boolean { return useContext(I18nHydrationContext); }