Skip to content

Commit 0553e6c

Browse files
authored
Merge pull request #3492 from deveshidwivedi/feat/auto-detect-language
Detect browser language to set default language for new users
2 parents dd21cca + 11cb236 commit 0553e6c

File tree

3 files changed

+100
-2
lines changed

3 files changed

+100
-2
lines changed

client/i18n.js

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ import {
2121
enIN
2222
} from 'date-fns/locale';
2323

24+
import getPreferredLanguage from './utils/language-utils';
25+
2426
const fallbackLng = ['en-US'];
2527

2628
export const availableLanguages = [
@@ -42,6 +44,21 @@ export const availableLanguages = [
4244
'ur'
4345
];
4446

47+
const detectedLanguage = getPreferredLanguage(
48+
availableLanguages,
49+
fallbackLng[0]
50+
);
51+
52+
let initialLanguage = detectedLanguage;
53+
54+
// if user has a saved preference (e.g., from redux or window.__INITIAL_STATE__), use that
55+
if (
56+
window.__INITIAL_STATE__?.preferences?.language &&
57+
availableLanguages.includes(window.__INITIAL_STATE__.preferences.language)
58+
) {
59+
initialLanguage = window.__INITIAL_STATE__.preferences.language;
60+
}
61+
4562
export function languageKeyToLabel(lang) {
4663
const languageMap = {
4764
be: 'বাংলা',
@@ -104,7 +121,7 @@ i18n
104121
// .use(LanguageDetector)// to detect the language from currentBrowser
105122
.use(Backend) // to fetch the data from server
106123
.init({
107-
lng: 'en-US',
124+
lng: initialLanguage,
108125
fallbackLng, // if user computer language is not on the list of available languages, than we will be using the fallback language specified earlier
109126
debug: false,
110127
backend: options,

client/modules/IDE/reducers/preferences.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import * as ActionTypes from '../../../constants';
2+
import i18n from '../../../i18n';
23

34
export const initialState = {
45
tabIndex: 0,
@@ -11,7 +12,7 @@ export const initialState = {
1112
gridOutput: false,
1213
theme: 'light',
1314
autorefresh: false,
14-
language: 'en-US',
15+
language: i18n.language,
1516
autocloseBracketsQuotes: true,
1617
autocompleteHinter: false
1718
};

client/utils/language-utils.js

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
/**
2+
* Utility functions for language detection and handling
3+
*/
4+
5+
function getPreferredLanguage(supportedLanguages = [], defaultLanguage = 'en') {
6+
if (typeof navigator === 'undefined') {
7+
return defaultLanguage;
8+
}
9+
10+
const normalizeLanguage = (langCode) => langCode.toLowerCase().trim();
11+
12+
const normalizedSupported = supportedLanguages.map(normalizeLanguage);
13+
14+
if (navigator.languages && navigator.languages.length) {
15+
const matchedLang = navigator.languages.find((browserLang) => {
16+
const normalizedBrowserLang = normalizeLanguage(browserLang);
17+
18+
const hasExactMatch =
19+
normalizedSupported.findIndex(
20+
(lang) => lang === normalizedBrowserLang
21+
) !== -1;
22+
23+
if (hasExactMatch) {
24+
return true;
25+
}
26+
27+
const languageOnly = normalizedBrowserLang.split('-')[0];
28+
const hasLanguageOnlyMatch =
29+
normalizedSupported.findIndex(
30+
(lang) => lang === languageOnly || lang.startsWith(`${languageOnly}-`)
31+
) !== -1;
32+
33+
return hasLanguageOnlyMatch;
34+
});
35+
36+
if (matchedLang) {
37+
const normalizedMatchedLang = normalizeLanguage(matchedLang);
38+
const exactMatchIndex = normalizedSupported.findIndex(
39+
(lang) => lang === normalizedMatchedLang
40+
);
41+
42+
if (exactMatchIndex !== -1) {
43+
return supportedLanguages[exactMatchIndex];
44+
}
45+
46+
const languageOnly = normalizedMatchedLang.split('-')[0];
47+
const languageOnlyMatchIndex = normalizedSupported.findIndex(
48+
(lang) => lang === languageOnly || lang.startsWith(`${languageOnly}-`)
49+
);
50+
51+
if (languageOnlyMatchIndex !== -1) {
52+
return supportedLanguages[languageOnlyMatchIndex];
53+
}
54+
}
55+
}
56+
57+
if (navigator.language) {
58+
const normalizedNavLang = normalizeLanguage(navigator.language);
59+
const exactMatchIndex = normalizedSupported.findIndex(
60+
(lang) => lang === normalizedNavLang
61+
);
62+
63+
if (exactMatchIndex !== -1) {
64+
return supportedLanguages[exactMatchIndex];
65+
}
66+
67+
const languageOnly = normalizedNavLang.split('-')[0];
68+
const languageOnlyMatchIndex = normalizedSupported.findIndex(
69+
(lang) => lang === languageOnly || lang.startsWith(`${languageOnly}-`)
70+
);
71+
72+
if (languageOnlyMatchIndex !== -1) {
73+
return supportedLanguages[languageOnlyMatchIndex];
74+
}
75+
}
76+
77+
return defaultLanguage;
78+
}
79+
80+
export default getPreferredLanguage;

0 commit comments

Comments
 (0)