1- import { useCallback , useEffect , useMemo , useState } from "react" ;
1+ import { useCallback , useEffect , useMemo , useState } from "react" ;
2+ import arMessages from "../locales/ar.json" ;
3+ import enMessages from "../locales/en.json" ;
4+ import {
5+ DEFAULT_LOCALE ,
6+ LOCALE_COOKIE ,
7+ isSupportedLocale ,
8+ localeMeta ,
9+ supportedLocales ,
10+ type Locale ,
11+ } from "./i18n-core" ;
212
3- type Messages = Record < string , string > ;
4-
5- export const supportedLocales = [ "en" , "ar" ] as const ;
6- export type Locale = ( typeof supportedLocales ) [ number ] ;
7- const storageKey = "app-locale" ;
13+ export {
14+ DEFAULT_LOCALE ,
15+ LOCALE_COOKIE ,
16+ getLocaleDir ,
17+ isSupportedLocale ,
18+ parseAcceptLanguage ,
19+ supportedLocales ,
20+ type Locale ,
21+ } from "./i18n-core" ;
822
9- let enMessagesCache : Messages | null = null ;
23+ type Messages = Record < string , string > ;
1024
11- const localeMeta : Record < Locale , { dir : "ltr" | "rtl" ; label : string } > = {
12- en : { dir : "ltr" , label : "English" } ,
13- ar : { dir : "rtl" , label : "\u0627\u0644\u0639\u0631\u0628\u064a\u0629" } ,
25+ const cookieMaxAge = 60 * 60 * 24 * 365 ;
26+ const messagesByLocale : Record < Locale , Messages > = {
27+ en : enMessages ,
28+ ar : arMessages ,
1429} ;
1530
1631async function loadMessages ( locale : Locale ) : Promise < Messages > {
17- switch ( locale ) {
18- case "ar" :
19- return ( await import ( "../locales/ar.json" ) ) . default ;
20- case "en" :
21- default :
22- return ( await import ( "../locales/en.json" ) ) . default ;
23- }
32+ return messagesByLocale [ locale ] ;
2433}
2534
26- function detectLocale ( ) : Locale {
27- if ( typeof window === "undefined" ) return "en" ;
28- const stored = window . localStorage . getItem ( storageKey ) as Locale | null ;
29- if ( stored && supportedLocales . includes ( stored ) ) return stored ;
30- const nav = navigator . language ?. split ( "-" ) ?. [ 0 ] ?. toLowerCase ( ) ;
31- if ( nav && supportedLocales . includes ( nav as Locale ) ) return nav as Locale ;
32- return "en" ;
35+ function persistLocale ( locale : Locale ) {
36+ if ( typeof window === "undefined" ) return ;
37+
38+ window . localStorage . setItem ( LOCALE_COOKIE , locale ) ;
39+ document . cookie = `${ LOCALE_COOKIE } =${ locale } ; path=/; max-age=${ cookieMaxAge } ; samesite=lax` ;
3340}
3441
35- export function useI18nProvider ( ) {
36- const [ locale , setLocaleState ] = useState < Locale > ( "en" ) ;
37- const [ messages , setMessages ] = useState < Messages > ( ( ) => {
38- if ( enMessagesCache ) return enMessagesCache ;
39- // eslint-disable-next-line @typescript-eslint/no-var-requires
40- enMessagesCache = require ( "../locales/en.json" ) ;
41- return enMessagesCache as Messages ;
42- } ) ;
42+ export function useI18nProvider ( initialLocale : Locale = DEFAULT_LOCALE ) {
43+ const [ locale , setLocaleState ] = useState < Locale > ( initialLocale ) ;
44+ const [ messages , setMessages ] = useState < Messages > ( ( ) => messagesByLocale [ initialLocale ] ) ;
4345 const [ ready , setReady ] = useState < boolean > ( true ) ;
4446
4547 const changeLocale = useCallback ( ( next : Locale ) => {
@@ -48,24 +50,25 @@ export function useI18nProvider() {
4850 . then ( ( m ) => {
4951 setMessages ( m ) ;
5052 setLocaleState ( next ) ;
51- if ( typeof window !== "undefined" ) {
52- window . localStorage . setItem ( storageKey , next ) ;
53- }
53+ persistLocale ( next ) ;
5454 setReady ( true ) ;
5555 } )
5656 . catch ( ( err ) => {
5757 console . warn ( "[i18n] failed to load locale, falling back to en" , err ) ;
58- if ( enMessagesCache ) setMessages ( enMessagesCache ) ;
59- setLocaleState ( "en" ) ;
58+ setMessages ( messagesByLocale [ DEFAULT_LOCALE ] ) ;
59+ setLocaleState ( DEFAULT_LOCALE ) ;
6060 setReady ( true ) ;
6161 } ) ;
6262 } , [ ] ) ;
6363
6464 useEffect ( ( ) => {
6565 if ( typeof window === "undefined" ) return ;
66- const detected = detectLocale ( ) ;
67- changeLocale ( detected ) ;
68- } , [ changeLocale ] ) ;
66+
67+ const stored = window . localStorage . getItem ( LOCALE_COOKIE ) ;
68+ if ( isSupportedLocale ( stored ) && stored !== locale ) {
69+ changeLocale ( stored ) ;
70+ }
71+ } , [ changeLocale , locale ] ) ;
6972
7073 useEffect ( ( ) => {
7174 if ( typeof document === "undefined" ) return ;
0 commit comments