Skip to content

Instantly share code, notes, and snippets.

@nemrosim
Last active March 27, 2022 17:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nemrosim/416580d2aaad08971801b05310d54afd to your computer and use it in GitHub Desktop.
Save nemrosim/416580d2aaad08971801b05310d54afd to your computer and use it in GitHub Desktop.
-import React, { useEffect, useState } from 'react';
+import React, { useCallback, useEffect, useState } from 'react';
import { I18nProvider as LinguiI18nProvider } from "@lingui/react";
import { i18n } from "@lingui/core";
+import {
+ detect,
+ fromCookie,
+ fromHtmlTag,
+ fromNavigator,
+ fromPath,
+ fromStorage,
+ fromSubdomain,
+ fromUrl,
+} from "@lingui/detect-locale"
import { I18nContext } from './I18nContext';
import { LocaleEnum } from "./types";
+const detectLocale = () => {
+
+ let fromPathResult;
+ try {
+ /*
+ Gets data from location.pathname
+ Will throw an error is index is wrong
+ Uncaught TypeError: Cannot read properties of undefined (reading 'replace')
+ */
+ fromPathResult = detect(fromPath(0));
+ } catch (e) {
+ fromPathResult = window.location.pathname
+ }
+
+ return {
+ url: detect(fromUrl("lang")),
+ storage: detect(fromStorage("lang", { useSessionStorage: false })),
+ /**
+ * Recovers the navigator language, it’s also compatible with old browsers like IE11
+ */
+ navigator: detect(fromNavigator()),
+ cookie: detect(fromCookie('lang')),
+ /*
+ Example:
+ <!DOCTYPE html>
+ <html lang="en">
+ </html>
+ */
+ tag: detect(fromHtmlTag('lang')),
+ fromPath: fromPathResult,
+ // Example: https://fr.url.com/
+ // gets data from location.href
+ fromSubdomain: detect(fromSubdomain(2)),
+ }
+};
+
+const isLocalePresent = (locale: string) => {
+ let isPresent = false;
+ Object.values(LocaleEnum).forEach(enumLocaleValue => {
+ if (enumLocaleValue === locale) {
+ isPresent = true;
+ }
+ })
+
+ return isPresent;
+}
+
export const I18nProvider: React.FC = ({ children }) => {
const [ locale, setLocale ] = useState(LocaleEnum.English);
+ const setLocaleIfPresent = useCallback((locale: string) => {
+ if (isLocalePresent(locale)) {
+ console.log('SET locale', locale)
+ setLocale(locale as LocaleEnum);
+ }
+ }, [])
+
+ useEffect(() => {
+ const { url, storage, cookie, navigator } = detectLocale();
+
+ // if previously data was saved to storage
+ if (storage) {
+ setLocaleIfPresent(storage)
+ // if url contains ?lang= query
+ } else if (url) {
+ setLocaleIfPresent(url)
+
+ } else if (navigator) {
+ setLocaleIfPresent(navigator)
+ }
+
+ }, [ setLocaleIfPresent ]);
+
+ const handleChangeLocale = (locale: LocaleEnum) => {
+ document.cookie = `lang=${locale}`;
+ localStorage.setItem('lang', locale)
+ setLocale(locale);
+ };
+
useEffect(() => {
// Dynamically load the catalogs
import(`../../locales/${locale}/messages`).then(module => {
@@ -27,16 +118,16 @@
}, [ locale ])
return (
<I18nContext.Provider
value={{
locale,
- setLocale
+ handleChangeLocale,
}}
>
<LinguiI18nProvider i18n={i18n}>
{children}
</LinguiI18nProvider>
</I18nContext.Provider>
);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment