Skip to content
This repository was archived by the owner on Aug 7, 2025. It is now read-only.

Commit fa46526

Browse files
committed
fix(isLanguageAvailable): do not return regionless-locales in older browsers with languageOnly set to false
1 parent 259ecbc commit fa46526

3 files changed

Lines changed: 47 additions & 16 deletions

File tree

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import preferredLocale from './'
2+
import * as isLocaleSupported from './utils/isLocaleSupported'
3+
4+
describe('preferredLocale', () => {
5+
describe('without Intl.Locale supported', () => {
6+
beforeEach(() => {
7+
jest.spyOn(isLocaleSupported, 'isLocaleSupported').mockReturnValue(false)
8+
})
9+
10+
it('handles region-less locales', () => {
11+
expect.assertions(1)
12+
jest.spyOn(navigator, 'languages', 'get').mockReturnValue([ 'en', 'en-US' ])
13+
const translations = [ 'fr-FR', 'id-ID', 'en-US' ]
14+
expect(preferredLocale(translations, 'en-US')).toBe('en-US')
15+
})
16+
})
17+
})

packages/preferred-locale/src/utils/availableLocales/index.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { isLanguageAvailable } from '../'
66
* @param {string[]} translatedLocales Translations provided by the application
77
* @param {Object} [options={}] Configuration options
88
* @param {boolean} [options.regionLowerCase=false] If true, returns `en-us` instead of `en-US`
9+
* @param {boolean} [options.languageOnly=false] If true, returns `en` instead of `en-US` or `en-us`
910
* @returns {Object[]} Locales supported by both the browser and application
1011
* @private
1112
*/
@@ -15,6 +16,7 @@ export const availableLocales = (
1516
options = {}
1617
) => {
1718
if (!options.regionLowerCase) options.regionLowerCase = false
19+
if (!options.languageOnly) options.languageOnly = false
1820

1921
return userLocales.filter((userLocale, index, array) => {
2022
const formattedLocale = options.regionLowerCase
@@ -29,7 +31,8 @@ export const availableLocales = (
2931
formattedLocale,
3032
translatedLocales,
3133
index,
32-
array
34+
array,
35+
options
3336
)
3437
})
3538
}

packages/preferred-locale/src/utils/isLanguageAvailable/index.js

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,28 +6,39 @@ import { isLocaleSupported } from '../'
66
* @param {string[]} translatedLocales Translations provided by the application
77
* @param {number} index The index of the unified browser locale in `array`
88
* @param {Object[]} array The unified browser locale array
9+
* @param {Object} [options={}] Configuration options
10+
* @param {boolean} [options.languageOnly=false] If true, returns `en` instead of `en-US` or `en-us`
911
* @returns {boolean} Is the language available?
1012
* @private
1113
*/
1214
export const isLanguageAvailable = (
1315
userLocale,
1416
translatedLocales,
1517
index,
16-
array
17-
) => translatedLocales.filter(translatedLocale => {
18-
// Strip the region code from both locales (en-gb -> en)
19-
const translatedLanguage = isLocaleSupported()
20-
? new Intl.Locale(translatedLocale).minimize().language
21-
: translatedLocale.split('-')[0]
22-
const browserLanguage = isLocaleSupported()
23-
? new Intl.Locale(userLocale).minimize().language
24-
: userLocale.split('-')[0]
18+
array,
19+
options = {}
20+
) => {
21+
if (!options.languageOnly) options.languageOnly = false
2522

26-
const isLanguageAvailable = translatedLanguage === browserLanguage
23+
return translatedLocales.filter(translatedLocale => {
24+
const localeSupported = isLocaleSupported()
25+
// Backwards compatibility for older browsers
26+
if (!localeSupported && !options.languageOnly && userLocale.split('-')[1] === undefined) return false
2727

28-
// Update the locale field to the canonical region if there is no translations for the browser-provided region
29-
// For example, en-XX (unknown region) to en-US (translated)
30-
if (isLanguageAvailable) array[index].locale = translatedLanguage
28+
// Strip the region code from both locales (en-gb -> en)
29+
const translatedLanguage = localeSupported
30+
? new Intl.Locale(translatedLocale).minimize().language
31+
: translatedLocale.split('-')[0]
32+
const browserLanguage = localeSupported
33+
? new Intl.Locale(userLocale).minimize().language
34+
: userLocale.split('-')[0]
3135

32-
return isLanguageAvailable
33-
}).length > 0
36+
const isLanguageAvailable = translatedLanguage === browserLanguage
37+
38+
// Update the locale field to the canonical region if there is no translations for the browser-provided region
39+
// For example, en-XX (unknown region) to en-US (translated)
40+
if (isLanguageAvailable) array[index].locale = translatedLanguage
41+
42+
return isLanguageAvailable
43+
}).length > 0
44+
}

0 commit comments

Comments
 (0)