@@ -19,12 +19,57 @@ export default function Subscribe(props) {
1919 const [ email , setEmail ] = useState ( "" )
2020 const [ customMessage , setCustomMessage ] = useState ( "" )
2121 const [ emailValid , setEmailValid ] = useState ( false )
22- const [ mounted , setMounted ] = useState ( false )
22+ const [ isReady , setIsReady ] = useState ( false )
2323
2424 useEffect ( ( ) => {
25- setTimeout ( ( ) => {
26- setMounted ( true )
27- } , 300 )
25+ const ensureResourcesLoaded = async ( ) => {
26+ try {
27+ // Wait for i18next to be initialized
28+ if ( ! i18next . isInitialized ) {
29+ await new Promise ( ( resolve ) => {
30+ const handler = ( ) => {
31+ i18next . off ( "initialized" , handler )
32+ resolve ( undefined )
33+ }
34+ i18next . on ( "initialized" , handler )
35+ } )
36+ }
37+
38+ // changeLanguage will wait for resources to load if they're not already loaded
39+ if ( props . lang && i18next . language !== props . lang ) {
40+ await changeLanguage ( props . lang )
41+ }
42+
43+ // Double-check that resources are actually loaded
44+ const targetLang = props . lang || i18next . language || "en"
45+ if ( i18next . hasResourceBundle ( targetLang , "translation" ) ) {
46+ setIsReady ( true )
47+ } else {
48+ // Wait for resources to be loaded
49+ await new Promise ( ( resolve ) => {
50+ const checkResources = ( ) => {
51+ if ( i18next . hasResourceBundle ( targetLang , "translation" ) ) {
52+ i18next . off ( "loaded" , checkResources )
53+ resolve ( undefined )
54+ }
55+ }
56+ i18next . on ( "loaded" , checkResources )
57+ // Check immediately in case resources are already loaded
58+ if ( i18next . hasResourceBundle ( targetLang , "translation" ) ) {
59+ i18next . off ( "loaded" , checkResources )
60+ resolve ( undefined )
61+ }
62+ } )
63+ setIsReady ( true )
64+ }
65+ } catch ( error ) {
66+ // If something goes wrong, still set ready to avoid blocking the UI
67+ console . error ( "Error loading i18next resources:" , error )
68+ setIsReady ( true )
69+ }
70+ }
71+
72+ ensureResourcesLoaded ( )
2873 } , [ props . lang ] )
2974
3075 useEffect ( ( ) => {
@@ -47,11 +92,9 @@ export default function Subscribe(props) {
4792 setEmail ( e . target . value )
4893 }
4994
50- if ( ! mounted ) {
95+ if ( ! isReady ) {
5196 return null
5297 }
53-
54- i18next . changeLanguage ( props . lang )
5598
5699 return (
57100 < div className = { clsx ( styles . container , "dark:bg-dark-highlight" ) } >
@@ -61,22 +104,28 @@ export default function Subscribe(props) {
61104 </ span >
62105
63106 < div className = { styles . copyBox } >
64- < div className = { styles . subscribeTitle } > { t ( "landing.NewsletterCTA.title" ) } </ div >
65- < div className = { styles . subscribeText } >
66- { t ( "landing.NewsletterCTA.text" ) }
67- </ div >
107+ < div className = { styles . subscribeTitle } > { t ( "landing.NewsletterCTA.title" ) } </ div >
108+ < div className = { styles . subscribeText } > { t ( "landing.NewsletterCTA.text" ) } </ div >
68109 </ div >
69110 < MailchimpSubscribe
70111 url = { url }
71- render = { ( { subscribe, status, message } : any ) => (
112+ render = { ( {
113+ subscribe,
114+ status,
115+ message,
116+ } : {
117+ subscribe : ( data : { EMAIL : string } ) => void
118+ status : string
119+ message : string
120+ } ) => (
72121 < div className = { styles . emailBox } >
73122 < EmailInput
74123 className = { styles . emailInput }
75124 value = { email }
76125 onChange = { handleChangeEmail }
77126 onClick = { ( ) => handleSubmit ( subscribe ) }
78127 onEnter = { ( ) => handleSubmit ( subscribe ) }
79- placeholder = { t ( "landing.NewsletterCTA.placeholder" ) }
128+ placeholder = { t ( "landing.NewsletterCTA.placeholder" ) }
80129 end = { status === "success" }
81130 />
82131 { customMessage && < div className = { styles . errorMessage } > { customMessage } </ div > }
0 commit comments