'use client'; import { NextIntlClientProvider } from 'next-intl'; import { createContext, useContext, useState, useEffect, ReactNode, } from 'react'; import Cookies from 'js-cookie'; import { useMemoizedFn } from 'ahooks'; type Locale = 'zh' | 'en'; interface LocaleContextType { locale: Locale; setLocale: (locale: Locale) => void; } const LocaleContext = createContext(undefined); export function useLocale() { const context = useContext(LocaleContext); if (!context) { throw new Error('useLocale must be used within IntlProvider'); } return context; } interface IntlProviderProps { children: ReactNode; } function setLocaleToCookie(locale: Locale) { if (typeof window === 'undefined') return; Cookies.set('locale', locale, { expires: 365, path: '/' }); } function getLocaleFromCookie(): Locale { if (typeof window === 'undefined') return 'en'; const cookieLocale = Cookies.get('locale') as Locale | undefined; if (cookieLocale && (cookieLocale === 'zh' || cookieLocale === 'en')) { return cookieLocale; } setLocaleToCookie('en'); return 'en'; } export function IntlProvider({ children }: IntlProviderProps) { const [locale, setLocaleState] = useState('en'); const [messages, setMessages] = useState>(); const loadLocale = useMemoizedFn(async (locale: Locale) => { // 动态加载, 提升首屏加载速度 const messages = await import(`@/locales/${locale}.ts`); setMessages(messages.default); }); useEffect(() => { const cookieLocale = getLocaleFromCookie(); if (cookieLocale) { loadLocale(cookieLocale); setLocaleState(cookieLocale); } }, []); const setLocale = useMemoizedFn((newLocale: Locale) => { setLocaleState(newLocale); setLocaleToCookie(newLocale); loadLocale(newLocale); }); if (!messages) return null; return ( {children} ); }