mirror of
https://github.com/Rain-kl/OpenFlare.git
synced 2026-11-12 21:44:22 +08:00
53 lines
1.5 KiB
TypeScript
53 lines
1.5 KiB
TypeScript
'use client';
|
|
|
|
import { useLayoutEffect, useState } from 'react';
|
|
import { NextIntlClientProvider } from 'next-intl';
|
|
import type { AbstractIntlMessages } from 'next-intl';
|
|
import type { ReactNode } from 'react';
|
|
import { resolveClientLocale } from '@/i18n/client';
|
|
import type { AppLocale } from '@/i18n/config';
|
|
import enMessages from '@/messages/en.json';
|
|
import zhCNMessages from '@/messages/zh-CN.json';
|
|
|
|
const messagesByLocale: Record<AppLocale, AbstractIntlMessages> = {
|
|
'zh-CN': zhCNMessages,
|
|
en: enMessages,
|
|
};
|
|
|
|
type Props = {
|
|
locale: AppLocale;
|
|
messages: AbstractIntlMessages;
|
|
children: ReactNode;
|
|
};
|
|
|
|
export function AppIntlProvider({
|
|
locale: ssrLocale,
|
|
messages: ssrMessages,
|
|
children,
|
|
}: Props) {
|
|
// Static exports start in the default English locale. Keep hydration aligned
|
|
// with that HTML, then apply an explicit preference before the hydrated UI
|
|
// paints instead of switching languages in a passive effect after paint.
|
|
const [clientLocale, setClientLocale] = useState<AppLocale | null>(null);
|
|
|
|
useLayoutEffect(() => {
|
|
const resolved = resolveClientLocale();
|
|
if (resolved !== ssrLocale) {
|
|
setClientLocale(resolved);
|
|
}
|
|
document.documentElement.lang = resolved;
|
|
}, [ssrLocale]);
|
|
|
|
const locale = clientLocale ?? ssrLocale;
|
|
|
|
return (
|
|
<NextIntlClientProvider
|
|
locale={locale}
|
|
messages={clientLocale ? messagesByLocale[clientLocale] : ssrMessages}
|
|
timeZone='Asia/Shanghai'
|
|
>
|
|
{children}
|
|
</NextIntlClientProvider>
|
|
);
|
|
}
|