Reputation: 2290
I am looking for a solution that will store state
locally when refreshing the browser.
Our app has many translations with a language selector but currently upon a browser refresh this state is reset to the default.
Within the app, as authorised we save the chosen language to Firebase and onMount
the chosen user language is shown, however, on our page without authentication, such as the login page and create page, this is not possible.
Currently, language is selected and stored as a state using Context
as
import React, { useReducer } from 'react';
// Translations
import EN from '../../../constants/translations/en.json';
import TR from '../../../constants/translations/tr.json';
import ES from '../../../constants/translations/es.json';
interface InterfaceState {
langCode?: string;
translate?: any;
dispatch: any;
}
const translations: any = {
en: EN,
tr: TR,
es: ES
};
const getTranslate = (langCode: string) => (key: string | number) =>
translations[langCode][key] || key;
const initialState = {
langCode: 'en',
translate: getTranslate('en'),
dispatch: ''
};
export const I18nContext = React.createContext<InterfaceState>(initialState);
export const I18nContextProvider = ({ children }: any) => {
const reducer = (state: any, action: { type: any; payload: any }) => {
switch (action.type) {
case 'setLanguage':
return {
langCode: action.payload,
translate: getTranslate(action.payload)
};
default:
return { ...initialState };
}
};
const [state, dispatch] = useReducer(reducer, initialState);
const value = { ...state, dispatch };
return <I18nContext.Provider value={value as any}>{children}</I18nContext.Provider>;
};
The language selector uses useContext
to set state and this works fine until the user refreshes the browser and the default langCode
is applied.
One solution I've tried that works but has required much to keep maintained, especially as it requires me to add additional steps to Link
components, is to history.push(pathname)
and add a string query with the langCode
in a string as
const onLanguageSelect = (data: any) => {
dispatch({ type: 'setLanguage', payload: data.value });
history.push(location.pathname + `?lang=` + data.value);
};
My question, how can I store the chosen state to session
or local
storage? And is this a viable and scalable solution, especially across multiple domains as app.example.com and example.com?
Upvotes: 1
Views: 76
Reputation: 2146
You can use iframe
to share what you have saved in localStorage
/sessionStorage
Here is the link
Upvotes: 1
Reputation: 321
Good question. I think local or session is not the option. As it is not saved across different subdomains. I think an option might be to use a cookie. Cookies can be shared with multiple sub domains without a problem.
Just save it in a cookie when you language is selected and fetch in in the default value of your context if it is defined.
Only downside is that some people have set their cookies off by default. So you might need to add a prompt that suggests the user to turn on their cookies for you application.
Upvotes: 0