[javascript] Best way to determine user's locale within browser

I have a website (Flash) localized into a dozen of languages and I want to auto-define a default value depending on the user's browser settings in order to minimize the steps to access the content.

FYI, I cannot use server-scripts due to proxy restrictions, so I guess JavaScript or ActionScript would be appropriate to solve the problem.

Questions:

  1. What would be the best method to 'guess' the user's locale?

  2. Are there any existing simple classes/functions that could help me out (no complex localization bundles)? Specially to break down all the possible languages into a smaller number (the translations I have) on a smart way.

  3. To which point can I trust such a solution?

  4. Any other workarounds or suggestions?

This question is related to javascript flash browser localization

The answer is


Combining the multiple ways browsers are using to store the user's language, you get this function :

const getNavigatorLanguage = () => {
  if (navigator.languages && navigator.languages.length) {
    return navigator.languages[0];
  } else {
    return navigator.userLanguage || navigator.language || navigator.browserLanguage || 'en';
  }
}

We first check the navigator.languages array for its first element.
Then we get either navigator.userLanguage or navigator.language.
If this fails we get navigator.browserLanguage.
Finally, we set it to 'en' if everything else failed.


And here's the sexy one-liner :

const getNavigatorLanguage = () => (navigator.languages && navigator.languages.length) ? navigator.languages[0] : navigator.userLanguage || navigator.language || navigator.browserLanguage || 'en';

There's a difference between the user's preferred languages and the system/browser locale.

A user can configure preferred languages in the browser, and these will be used for navigator.language(s), and used when requesting resources from a server, to request content according to a list of language priorities.

However, the browser locale will decide how to render number, date, time and currency. This setting is likely the highest ranking language, but there is no guarantee. On Mac and Linux, the locale is decided by the system regardless of the user language preferences. On Windows is can be elected among the languages in the preferred list on Chrome.

By using Intl (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl), developers can override/set the locale to use to render these things, but there are elements that cannot be overridden, such as the <input type="date"> format.

To properly extract this language, the only way I've found is:

(new Intl.NumberFormat()).resolvedOptions().locale

(Intl.NumberFormat().resolvedOptions().locale also seems to work)

This will create a new NumberFormat instance for the default locale and then reading back the locale of those resolved options.


This article suggests the following properties of the browser's navigator object:

  • navigator.language (Netscape - Browser Localization)
  • navigator.browserLanguage (IE-Specific - Browser Localized Language)
  • navigator.systemLanguage (IE-Specific - Windows OS - Localized Language)
  • navigator.userLanguage

Roll these into a javascript function and you should be able to guess the right language, in most circumstances. Be sure to degrade gracefully, so have a div containing your language choice links, so that if there is no javascript or the method doesn't work, the user can still decide. If it does work, just hide the div.

The only problem with doing this on the client side is that either you serve up all the languages to the client, or you have to wait until the script has run and detected the language before requesting the right version. Perhaps serving up the most popular language version as a default would irritate the fewest people.

Edit: I'd second Ivan's cookie suggestion, but make sure the user can always change the language later; not everyone prefers the language their browser defaults to.


You said your website has Flash, then, as another option, you can get operation system's language with flash.system.Capabilities.language— see How to determine OS language within browser to guess an operation system locale.


You can also try to get the language from the document should might be your first port of call, then falling back to other means as often people will want their JS language to match the document language.

HTML5:

document.querySelector('html').getAttribute('lang')

Legacy:

document.querySelector('meta[http-equiv=content-language]').getAttribute('content')

No real source is necessarily 100% reliable as people can simply put in the wrong language.

There are language detection libraries that might let you determine the language by content.


I did a bit of research regarding this & I have summarised my findings so far in below table

enter image description here

So the recommended solution is to write a a server side script to parse the Accept-Language header & pass it to client for setting the language of the website. It's weird that why the server would be needed to detect the language preference of client but that's how it is as of now There are other various hacks available to detect the language but reading the Accept-Language header is the recommended solution as per my understanding.


I used all the answers and created a single line solution:

const getLanguage = () => navigator.userLanguage || (navigator.languages && navigator.languages.length && navigator.languages[0]) || navigator.language || navigator.browserLanguage || navigator.systemLanguage || 'en';

console.log(getLanguage());

You can use http or https.

https://ip2c.org/XXX.XXX.XXX.XXX or https://ip2c.org/?ip=XXX.XXX.XXX.XXX |

  • standard IPv4 from 0.0.0.0 to 255.255.255.255

https://ip2c.org/s or https://ip2c.org/self or https://ip2c.org/?self |

  • processes caller's IP
  • faster than ?dec= option but limited to one purpose - give info about yourself

Reference: https://about.ip2c.org/#inputs


On Chrome and Firefox 32+, navigator.languages contains an array of locales in order of user preference, and is more accurate than navigator.language, however to make it backwards-compatible (Tested Chrome / IE / Firefox / Safari), then use this:

function getLang()
{
 if (navigator.languages != undefined) 
 return navigator.languages[0]; 
 else 
 return navigator.language;
}

Examples related to javascript

need to add a class to an element How to make a variable accessible outside a function? Hide Signs that Meteor.js was Used How to create a showdown.js markdown extension Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Summing radio input values How to execute an action before close metro app WinJS javascript, for loop defines a dynamic variable name Getting all files in directory with ajax

Examples related to flash

Assign command output to variable in batch file How to detect when a youtube video finishes playing? Error #2032: Stream Error How to embed a video into GitHub README.md? Want custom title / image / description in facebook share link from a flash app Flash CS4 refuses to let go How to add link to flash banner How can I detect if Flash is installed and if not, display a hidden div that informs the user? differences between using wmode="transparent", "opaque", or "window" for an embedded object on a webpage Best way to determine user's locale within browser

Examples related to browser

How to force reloading a page when using browser back button? How do we download a blob url video How to prevent a browser from storing passwords How to Identify Microsoft Edge browser via CSS? Edit and replay XHR chrome/firefox etc? Communication between tabs or windows How do I render a Word document (.doc, .docx) in the browser using JavaScript? "Proxy server connection failed" in google chrome Chrome - ERR_CACHE_MISS How to check View Source in Mobile Browsers (Both Android && Feature Phone)

Examples related to localization

What's NSLocalizedString equivalent in Swift? Best practice multi language website Best practice for localization and globalization of strings and labels How to change language of app when user selects language? Lint: How to ignore "<key> is not translated in <language>" errors? Using ResourceManager How do I set the default locale in the JVM? What is the list of supported languages/locales on Android? Android: how to get the current day of the week (Monday, etc...) in the user's language? Get the current language in device