JavaScript for detecting browser language preference [duplicate]
Asked Answered
U

26

536

I have been trying to detect the browser language preference using JavaScript.

If I set the browser language in IE in Tools>Internet Options>General>Languages, how do I read this value using JavaScript?

Same problem for Firefox. I'm not able to detect the setting for tools>options>content>languages using navigator.language.

Using navigator.userLanguage , it detects the setting done thru Start>ControlPanel>RegionalandLanguageOptions>Regional Options tab.

I have tested with navigator.browserLanguage and navigator.systemLanguage but neither returns the value for the first setting(Tools>InternetOptions>General>Languages)

I found a link which discusses this in detail, but the question remains unanswered :(

Unclean answered 25/6, 2009 at 11:8 Comment(1)
There is now (2020) an experimental feature supported by all browsers that returns an array of language preference: navigator.languages //["en-US", "zh-CN", "ja-JP"]Whipstitch
O
342

I think the main problem here is that the browser settings don't actually affect the navigator.language property that is obtained via javascript.

What they do affect is the HTTP 'Accept-Language' header, but it appears this value is not available through javascript at all. (Probably why @anddoutoi states he can't find a reference for it that doesn't involve server side.)

I have coded a workaround: I've knocked up a google app engine script at http://ajaxhttpheaders.appspot.com that will return you the HTTP request headers via JSONP.

(Note: this is a hack only to be used if you do not have a back end available that can do this for you. In general you should not be making calls to third party hosted javascript files in your pages unless you have a very high level of trust in the host.)

I intend to leave it there in perpetuity so feel free to use it in your code.

Here's some example code (in jQuery) for how you might use it

$.ajax({ 
    url: "http://ajaxhttpheaders.appspot.com", 
    dataType: 'jsonp', 
    success: function(headers) {
        language = headers['Accept-Language'];
        nowDoSomethingWithIt(language);
    }
});

Hope someone finds this useful.

Edit: I have written a small jQuery plugin on github that wraps this functionality: https://github.com/dansingerman/jQuery-Browser-Language

Edit 2: As requested here is the code that is running on AppEngine (super trivial really):

class MainPage(webapp.RequestHandler):
    def get(self):
        headers = self.request.headers
        callback = self.request.get('callback')

        if callback:
          self.response.headers['Content-Type'] = 'application/javascript'
          self.response.out.write(callback + "(")
          self.response.out.write(headers)
          self.response.out.write(")")
        else:
          self.response.headers['Content-Type'] = 'text/plain'
          self.response.out.write("I need a callback=")

application = webapp.WSGIApplication(
                                     [('/', MainPage)],
                                     debug=False)

def main():
    run_wsgi_app(application)

if __name__ == "__main__":
    main()

Edit3: Have open sourced the app engine code here: https://github.com/dansingerman/app-engine-headers

Omidyar answered 26/7, 2010 at 13:52 Comment(14)
@msec I have posted the Python appengine script as requested. Note, if server side is available, this should be pretty simple in any language - this service really only needs to exist for those that don't have (or don't want to have) a server side component.Omidyar
hi dan, this question gots 14k views and still counting - maybe you want to release your script on github? regards, msecIncendiarism
Are there other reliable sites that return HTTP request headers like Google? What I'm trying to do is redirecting user to their browswer language settings, and my site is global. So I need to rely on the site globally available and permenant.Turbary
@deckard ummm - the Internet is global. The appengine script should work fine anywhere on the Internet. However - this is really a hack for devs without a backend available - it should not be used in a 'real' site where you have control of a the back end.Omidyar
@DanSingerman, interesting script. However,you should use application/javascript for JSONP. Also, this is not technically valid JSONP, since you're using simple quotes, but that shouldn't matter for most purposes.Washbasin
@MatthewFlaschen you're quite right (In my defence I wrote the script in about 5 minutes 2 years ago.) I'll fix it up when I have a chance.Omidyar
@DanSingerman, thanks. "simple quotes" should have been "single quotes".Washbasin
Just wondering, what is the different between navigator.language and Accept-Language...Sesquioxide
@AwQiruiGuo the former is usually the browser's UI language, while the latter is an ordered list of languages the user prefers to view content in.Stanislaus
If the third party service should be more safe it should enable CORS ;)Oakes
Please note header['Accept-Language'] will get different result base on your browser.Pacific
a much better cross-browser solution is now available, see @MarcoDemaio's answer, explained here gu.illau.me/posts/…Stumper
I guess this might be out of date, because changing the language definitely did change the navigation.languages value. Also if you add a new language and move it to the top of the list, then you will get that value when you query on navigation.language. Also note that IE / Edge have been using the same engine as chrome for quite some time now, so it should be enough to use navigator.langauge (primary language) or navigator.languages (array of all languages)Concern
Is there a non Jquery version of this?Peachy
P
326
var language = window.navigator.userLanguage || window.navigator.language;
alert(language); //works IE/SAFARI/CHROME/FF

window.navigator.userLanguage is IE only and it's the language set in Windows Control Panel - Regional Options and NOT browser language, but you could suppose that a user using a machine with Window Regional settings set to France is probably a French user.

navigator.language is FireFox and all other browser.

Some language code: 'it' = italy, 'en-US' = english US, etc.


As pointed out by rcoup and The WebMacheter in comments below, this workaround won't let you discriminate among English dialects when users are viewing website in browsers other than IE.

window.navigator.language (Chrome/FF/Safari) returns always browser language and not browser's preferred language, but: "it's pretty common for English speakers (gb, au, nz, etc) to have an en-us version of Firefox/Chrome/Safari." Hence window.navigator.language will still return en-US even if the user preferred language is en-GB.

Patti answered 2/11, 2010 at 16:25 Comment(20)
Does navigator.language always return the same value for a particular language (e.g. ja-jp for Japanese)? Or, the value / format varies across browsers / OS?Unintelligible
I'm not sure, but you can check for a substring of it, i.e. if(language.indexOf('jp') !== -1) alert('this is japanese')Patti
This is not correct. Calling navigator.language in Chrome will return the language Chrome is displayed in, NOT the user's preferred language (which is the language at the top of the languages list).Ammons
@Anzeo: low are chances of having you site visited by users that speak in one language, but install a browser in another language and later they also set another preferred language. As said by others there is no decent way, my answer is a simple short workaround for a task that usually does not end up into fatal errors. If you have to be absolutely sure of what language the user uses you could always ask him by adding on your site a select list and save its choice into a cookie.Patti
@MarcoDemaio the OP asks a solution to detect the preference of the user. As Chrome is confusing in these settings, I added the note for future reference. We had the problem recently on our project and had to use the accepted answer. It's to determine the default, because our users can also set their preferred language on the platform. However this setting might be missing, hence the need of a default.Ammons
@MarcoDemaio it's pretty common for English speakers (gb, au, nz, etc) to have an en-us version of Firefox/Chrome/Safari. Sometimes en-gb builds exist but they're not popular, and there's certainly none for other en variants.Cowie
@rcoup: sorry, but i don't unsertsand youyr comment. Brits, Aussies, etc. they do all speak in English, and the 'Browser Language Preference' detected by my code will be exactly 'English'.Patti
I think you might be confusing the browser's configured language with the browser's language preference. The first controls the menus, etc on the browser, the later affects the languages that the browser sends in the header to servers asking for those languages in response. So if the server denies your language and resorts to English you'd want to use English, not the browser's language.Descent
Chrome has window.navigator.languages with array of user preferred languages.Baron
@Baron window.navigator.languages represents alphabetically sorted list of languages available in system for text input. For example: my system's UI and Chrome language is "ru". Also my native languages are "ru" (Russian) and "uk" (Ukrainian), so I have enabled keyboard layouts for these languages (as well as English layout) and Chrome for window.navigator.languages returns ["en-US", "en", "ru", "uk"]. Absolutely different order than my preference and language of my UI.Georgettageorgette
Due to said above, navigator.languages can't be used for any kind of strict detection for user's language preference order. It can be used to obtain generic information about user, not his preferences.Georgettageorgette
@stunpix - maybe Chrome auto add keybord layouts to preferred languages. But you can edit this list and window.navigator.languages has ordered list of languages from preferences: chrome://settings/languagesBaron
@Baron yep, seems Chrome do this at install time, since any changes in keyboard layout settings later do not change that Chrome setting. Anyway, average user do not change these language settings in browser, so no one should rely on them as on user's languages that are sorted by user preference. That's not true.Georgettageorgette
Another observation with Chrome: for pages with foreign languages browser asks to translate these pages to one of languages defined in settings, but once you click in popped bar "never translate this language" – this language will be added to you language list. So when user is getting annoyed with this translation bar, he can press "never translate" button to just stop it popping. Is this preferred user language in such case? I think no.Georgettageorgette
It is pretty common for aware non-native-english speakers to install browser in English language to be able to troubleshoot easier, and still prefer another language for non-technical stuff.Trubow
@CodeGust: The link no longer works. Can you find a replacement?Norfolk
@MarcelWaldvogel web.archive.org/web/20170616234605/http://blog.ksol.fr/… cached versionLir
@thomaux, no longer true. Now navigator.language in Chrome returns the first element of the list navigator.languages. This change makes it now impossible to know for sure the language of the browser's UI.Backstairs
The Accept-Language HTTP header in every HTTP request from the user's browser uses the same value for the navigator.languages property except for the extra qvalues (quality values) field (e.g. en-US;q=0.8). from developer.mozilla.org/en-US/docs/Web/API/NavigatorLanguage/…Dibs
developer.mozilla.org/en-US/docs/Web/API/Navigator/languages Clearly states that navigator.language is the first element in the navigator.languages array.Concern
I
235

Update of year 2014.

Now there is a way to get Accept-Languages in Firefox and Chrome using navigator.languages (works in Chrome >= 32 and Firefox >= 32)

Also, navigator.language in Firefox these years reflects most preferred language of content, not language of UI. But since this notion is yet to be supported by other browsers, it is not very useful.

So, to get most preferred content language when possible, and use UI language as fallback:

navigator.languages
    ? navigator.languages[0]
    : (navigator.language || navigator.userLanguage)
Intromit answered 1/9, 2014 at 10:20 Comment(13)
An alternative implementation which gets the preferred list of languages, or falls back to the UI language (both as arrays) is: window.navigator.languages || [window.navigator.language || window.navigator.userLanguage]Churchwarden
Note that this does not work in our 'most-favorite' browser, IE (tested with IE 11).Galilee
His answer works fine in IE (tested 8-11). This should be the accepted answer.Coarsen
Getting language with navigator.languages[0] is bad idea. My system's default language is Russian and navigator.language returns correct lang code "ru". But navigator.languages returns ["en-US", "en", "ru", "uk"]. So getting language with 0 index will give you "en-US" which is incorrect for my system. Please don't use navigator.languages to detect current system's language.Georgettageorgette
And one more thing: navigator.languages represents alphabetically(!) sorted list of languages available for text input in user's system. They are not sorted in order of user's preference.Georgettageorgette
@stunpix this is not about system's language, but about in-browser preference. Which might or might not coincide with system's language, depending on which browser was installed. I suggest you take a look at your browser's settings. Firefox: Preferences-Content-Languages, Chrome: Settings (advanced) - LanguagesIntromit
@stunpix No, this is not correct. The order of prefered languages in the array reflects the order set by user: developer.mozilla.org/en-US/docs/Web/API/NavigatorLanguage/…Giza
@Giza For some reason this was correct on moment of writing, because I had setup that always returned me sorted array, despite of my settings (I double checked that). Now it's no longer correct and I can't reproduce my previous statement, so it's no longer correct.Georgettageorgette
BTW, navigator.language[s] have unstable behavior across browsers and you should consider this behavior: navigator.language is a browser's UI lang. Chrome automatically sets its UI lang to system's, but FF doesn't do that automatically, so FF's lang could be != system's lang (for example freshly installed Ubuntu has FF with only english UI and other langs must be installed manually). navigator.languages – user's order preference. Chrome changes this list by pushing current system's lang to top of list, but FF still has a static list which should be sorted manually.Georgettageorgette
All good. I've just checked myself (hate to do that, as you have to restart the browser - at least chrome). 1. navigator.languages - array is in the order you arrange your languages in browser settings (chrome is less intuitive that you can order them, as there is no indicator that you can drag the items in the list; Firefox has move up/down buttons) 2. navigator.language - returns the current language (the one set as default) Of course, I've tried in Chrome and Firefox, not sure about IE and what navigator.userLanguage returns... but I'm not even opening "that" (ie IE) :)))Boiler
I have my OS language (i.e. Chrome's UI language) set to en_US, preferred browser languages set to de, en_US, en_GB, en in that order. navigator.language returns "de" for me, so it seems to be equivalent to navigator.languages[0], at least in more recent versions of Chrome.Kofu
Yes, can confirm it works now in Chrome 65 on Mac. Interestingly the bug about navigator.language is not closed yet bugs.chromium.org/p/chromium/issues/detail?id=101138Intromit
One liner is const langs = [].concat(navigator.languages, navigator.language, navigator.userLanguage, navigator.browserLanguage, navigator.systemLanguage).filter(Boolean);Okeechobee
B
72

I came across this piece of code to detect browser's language in Angular Translate module, which you can find the source here. I slightly modified the code by replacing angular.isArray with Array.isArray to make it independent of Angular library.

var getFirstBrowserLanguage = function () {
    var nav = window.navigator,
    browserLanguagePropertyKeys = ['language', 'browserLanguage', 'systemLanguage', 'userLanguage'],
    i,
    language;

    // support for HTML 5.1 "navigator.languages"
    if (Array.isArray(nav.languages)) {
      for (i = 0; i < nav.languages.length; i++) {
        language = nav.languages[i];
        if (language && language.length) {
          return language;
        }
      }
    }

    // support for other well known properties in browsers
    for (i = 0; i < browserLanguagePropertyKeys.length; i++) {
      language = nav[browserLanguagePropertyKeys[i]];
      if (language && language.length) {
        return language;
      }
    }

    return null;
  };

console.log(getFirstBrowserLanguage());
Belak answered 17/3, 2015 at 17:44 Comment(6)
This seems more reliable than other JS answers, e.g. the check on language.length means it will skip empty items in the languages array (if that even happens?)Bawl
To support older browsers when detecting that nav.languages is an array, you should use: Object.prototype.toString.call(nav.languages) === '[object Array]'Kathleenkathlene
To clarify: older browsers = ( IE <=8.0 )Noletta
EamonnM's edit of this code is probably more optimal, see: https://mcmap.net/q/41258/-javascript-for-detecting-browser-language-preference-duplicateMousey
This works just fine for what I intend to use it for.Radiomicrometer
For those from the future, please note that the Angular Translate project has been discontinued since 2024-Jan-15, and this project is now archived, according to their official homepage.Titty
G
56

let lang = window.navigator.languages ? window.navigator.languages[0] : null;
    lang = lang || window.navigator.language || window.navigator.browserLanguage || window.navigator.userLanguage;

let shortLang = lang;
if (shortLang.indexOf('-') !== -1)
    shortLang = shortLang.split('-')[0];

if (shortLang.indexOf('_') !== -1)
    shortLang = shortLang.split('_')[0];

console.log(lang, shortLang);

I only needed the primary component for my needs, but you can easily just use the full string. Works with latest Chrome, Firefox, Safari and IE10+.

Gabriel answered 12/11, 2014 at 14:16 Comment(0)
M
41

var language = navigator.languages && navigator.languages[0] || // Chrome / Firefox
               navigator.language ||   // All browsers
               navigator.userLanguage; // IE <= 10

console.log(language);

Try PWA Template https://github.com/StartPolymer/progressive-web-app-template

Middlemost answered 1/7, 2016 at 17:0 Comment(1)
Just run your script, got en-US, on osX El Capitan in Spanish, Chrome set in Spanish, from Barcelona .. The list of allowed languages, and picking up the first of it navigator.languages[0], is not the actual language the user is using.Enterotomy
F
23

navigator.userLanguage for IE

window.navigator.language for firefox/opera/safari

Folklore answered 25/6, 2009 at 11:40 Comment(2)
navigator.userLanguage wont give him what he wants. From userLanguage-docs: This property reflects the setting in the "Your locale (location)" box in the Regional Options of Control Panel for example, "English (United States).Fishbowl
It actually says it will return "any of the possible return values listed in the Language Codes." such as "en" or "en-gb" msdn.microsoft.com/en-us/library/ie/ms533052.aspx msdn.microsoft.com/en-us/library/ie/ms534713.aspxKeefer
B
22

I've been using Hamid's answer for a while, but it in cases where the languages array is like ["en", "en-GB", "en-US", "fr-FR", "fr", "en-ZA"] it will return "en", when "en-GB" would be a better match.

My update (below) will return the first long format code e.g. "en-GB", otherwise it will return the first short code e.g. "en", otherwise it will return null.

function getFirstBrowserLanguage() {
        var nav = window.navigator,
            browserLanguagePropertyKeys = ['language', 'browserLanguage', 'systemLanguage', 'userLanguage'],
            i,
            language,
            len,
            shortLanguage = null;

        // support for HTML 5.1 "navigator.languages"
        if (Array.isArray(nav.languages)) {
            for (i = 0; i < nav.languages.length; i++) {
                language = nav.languages[i];
                len = language.length;
                if (!shortLanguage && len) {
                    shortLanguage = language;
                }
                if (language && len>2) {
                    return language;
                }
            }
        }

        // support for other well known properties in browsers
        for (i = 0; i < browserLanguagePropertyKeys.length; i++) {
            language = nav[browserLanguagePropertyKeys[i]];
            //skip this loop iteration if property is null/undefined.  IE11 fix.
            if (language == null) { continue; } 
            len = language.length;
            if (!shortLanguage && len) {
                shortLanguage = language;
            }
            if (language && len > 2) {
                return language;
            }
        }

        return shortLanguage;
    }

console.log(getFirstBrowserLanguage());

Update: IE11 was erroring when some properties were undefined. Added a check to skip those properties.

Bawl answered 1/10, 2017 at 16:7 Comment(4)
It works on every browser I've tested - desktop and mobile. Which browser are you having problems with?Bawl
'browserLanguage', 'systemLanguage and, 'userLanguage' are not properties of chrome and firefox.. but 'language' is present in all browsers.. My bad that I didn't see that it would return first short code which answers the question.. Deleting my previous comment..Equalizer
How common is it a problem people have preferences in the order ["en", "en-GB"] but want the preferences the other way around. I thought the languages were meant to be in the order of user preference. if it were ["fr", "en-GB"], wouldn't the preference be for French?Eugeniaeugenics
@Eugeniaeugenics That's a good point. It would depend on what you need from it. For ["en", "en-GB"] I would want to get "en-GB" as it's a more specific version of the same language. ["fr", "en-GB"] is different as they are different languages, and "fr" could be a better result.Bawl
X
21

I've just come up with this. It combines newer JS destructuring syntax with a few standard operations to retrieve the language and locale.

var [lang, locale] = (
    (
        (
            navigator.userLanguage || navigator.language
        ).replace(
            '-', '_'
        )
    ).toLowerCase()
).split('_');

Hope it helps someone

Xerophilous answered 7/3, 2017 at 13:45 Comment(0)
B
17

There is no decent way to get that setting, at least not something browser independent.

But the server has that info, because it is part of the HTTP request header (the Accept-Language field, see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.4)

So the only reliable way is to get an answer back from the server. You will need something that runs on the server (like .asp, .jsp, .php, CGI) and that "thing" can return that info. Good examples here: http://www.developershome.com/wap/detection/detection.asp?page=readHeader

Bordelon answered 10/11, 2009 at 10:36 Comment(2)
Keep in mind that this is not a particularly reliable way of serving the "correct" language to the user. Many users will want an alternate option - don't leave them stranded!Flog
100% agree. Using that info it a best guess. You should allow the user to override it, if you get it wrong. And if there is a possibility that the user returns, you might remember that choice in a cookie. If the site requires authentication, you might have that info in a user profile.Bordelon
F
9

I can't find a single reference that state that it's possible without involving the serverside.

MSDN on:

From browserLanguage:

In Microsoft Internet Explorer 4.0 and earlier, the browserLanguage property reflects the language of the installed browser's user interface. For example, if you install a Japanese version of Windows Internet Explorer on an English operating system, browserLanguage would be ja.

In Internet Explorer 5 and later, however, the browserLanguage property reflects the language of the operating system regardless of the installed language version of Internet Explorer. However, if Microsoft Windows 2000 MultiLanguage version is installed, the browserLanguage property indicates the language set in the operating system's current menus and dialogs, as found in the Regional Options of the Control Panel. For example, if you install a Japanese version of Internet Explorer 5 on an English (United Kingdom) operating system, browserLanguage would be en-gb. If you install Windows 2000 MultiLanguage version and set the language of the menus and dialogs to French, browserLanguage would be fr, even though you have a Japanese version of Internet Explorer.

Note This property does not indicate the language or languages set by the user in Language Preferences, located in the Internet Options dialog box.

Furthermore, it looks like browserLanguage is deprecated cause IE8 doesn't list it

Fishbowl answered 25/6, 2009 at 11:46 Comment(3)
+1, but where did you read that navigator.browserLanguage is deprecated? It's not written in the links to the MSDN articles in you answer, and I just tested it in IE11 and it works! I don't have IE8 anymore, but I tested it with the IE8 simulator and it works (I know the IE8 simulator is not the best option to test things).Patti
Hmm, yeah that seems weird. But I have no clue how I came to that conclusion 5 years ago >.<Fishbowl
@Fishbowl It is not available in IE 8, because it was introduced in IE 9, so it's exactly the opposite of what you though.Polyurethane
F
9

I had the same problem, and I wrote the following front-end only library that wraps up the code for multiple browsers. It's not much code, but nice to not have to copy and paste the same code across multiple websites.

Get it: acceptedlanguages.js

Use it:

<script src="acceptedlanguages.js"></script>
<script type="text/javascript">
  console.log('Accepted Languages:  ' + acceptedlanguages.accepted);
</script>

It always returns an array, ordered by users preference. In Safari & IE the array is always single length. In FF and Chrome it may be more than one language.

Femoral answered 21/7, 2015 at 5:49 Comment(0)
T
9

I would like to share my code, because it works and it is different than the others given anwers. In this example, if you speak French (France, Belgium or other French language) you are redirected on the French page, otherwise on the English page, depending on the browser configuration:

<script type="text/javascript">
$(document).ready(function () {
    var userLang = navigator.language || navigator.userLanguage;
    if (userLang.startsWith("fr")) {
            window.location.href = '../fr/index.html';
    }
    else {
            window.location.href = '../en/index.html';
    }
});
</script>
Thermel answered 22/5, 2017 at 13:24 Comment(0)
M
7

If you only need to support certain modern browsers then you can now use:

navigator.languages

which returns an array of the user's language preferences in the order specified by the user.

As of now (Sep 2014) this works on: Chrome (v37), Firefox (v32) and Opera (v24)

But not on: IE (v11)

Mender answered 19/9, 2014 at 15:5 Comment(1)
In case it helps anyone else, I had thought this would work in Safari in iOS 8 since I thought it fell in the modern category. I was wrong.Chalutz
T
7

Javascript way:

var language = window.navigator.userLanguage || window.navigator.language;//returns value like 'en-us'

If you are using jQuery.i18n plugin, you can use:

jQuery.i18n.browserLang();//returns value like '"en-US"'
Truthvalue answered 2/4, 2015 at 9:45 Comment(0)
G
7

If you are developing a Chrome App / Extension use the chrome.i18n API.

chrome.i18n.getAcceptLanguages(function(languages) {
  console.log(languages);
  // ["en-AU", "en", "en-US"]
});
Gondola answered 6/5, 2015 at 1:37 Comment(2)
I like this. It's chrome specific, but doesn't electron use chromium under the hood? Does this work for just chrome, or any chromium projectXerophilous
This is only available from within a Chrome Extension. Its not available in Chrome on a regular web page. I'm not sure about Electron.Gondola
H
6

DanSingerman has a very good solution for this question.

The only reliable source for the language is in the HTTP-request header. So you need a server-side script to reply the request-header or at least the Accept-Language field back to you.

Here is a very simple Node.js server which should be compatible with DanSingermans jQuery plugin.

var http = require('http');
http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end(JSON.stringify(req.headers));
}).listen(80,'0.0.0.0');
Henni answered 5/11, 2011 at 8:39 Comment(1)
His plugin uses JSONP, so I don't think this will be compatible.Washbasin
M
6

For what it's worth, Wikimedia's Universal Language Selector library has hooks for doing this: https://www.mediawiki.org/wiki/Extension:UniversalLanguageSelector

See the function getFrequentLanguageList in resources/js/ext.uls.init.js . Direct link: https://gerrit.wikimedia.org/r/gitweb?p=mediawiki/extensions/UniversalLanguageSelector.git;a=blob;f=resources/js/ext.uls.init.js;hb=HEAD

It still depends on the server, or more specifically, the MediaWiki API. The reason I'm showing it is that it may provide a good example of getting all the useful information about the user's language: browser language, Accept-Language, geolocation (with getting country/language info from the CLDR), and of course, user's own site preferences.

Milliliter answered 15/11, 2012 at 8:19 Comment(0)
M
2

Dan Singerman's answer has an issue that the header fetched has to be used right away, due to the asynchronous nature of jQuery's ajax. However, with his google app server, I wrote the following, such that the header is set as part of the initial set up and can be used at later time.

<html>
<head>
<script>

    var bLocale='raw'; // can be used at any other place

    function processHeaders(headers){
        bLocale=headers['Accept-Language'];
        comma=bLocale.indexOf(',');
        if(comma>0) bLocale=bLocale.substring(0, comma);
    }

</script>

<script src="jquery-1.11.0.js"></script>

<script type="application/javascript" src="http://ajaxhttpheaders.appspot.com?callback=processHeaders"></script>

</head>
<body>

<h1 id="bLocale">Should be the browser locale here</h1>

</body>

<script>

    $("#bLocale").text(bLocale);

</script>
</html>
Maretz answered 5/2, 2014 at 23:25 Comment(0)
F
1

If you don't want to rely on an external server and you have one of your own you can use a simple PHP script to achieve the same behavior as @DanSingerman answer.

languageDetector.php:

<?php
$lang = substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2);
echo json_encode($lang);
?>

And just change this lines from the jQuery script:

url: "languageDetector.php",
dataType: 'json',
success: function(language) {
    nowDoSomethingWithIt(language);
}
Flintlock answered 23/2, 2015 at 13:45 Comment(0)
S
0

If you have control of a backend and are using django, a 4 line implementation of Dan's idea is:

def get_browser_lang(request):
if request.META.has_key('HTTP_ACCEPT_LANGUAGE'):
    return JsonResponse({'response': request.META['HTTP_ACCEPT_LANGUAGE']})
else:
    return JsonResponse({'response': settings.DEFAULT_LANG})

then in urls.py:

url(r'^browserlang/$', views.get_browser_lang, name='get_browser_lang'),

and on the front end:

$.get(lg('SERVER') + 'browserlang/', function(data){
    var lang_code = data.response.split(',')[0].split(';')[0].split('-')[0];
});

(you have to set DEFAULT_LANG in settings.py of course)

Scupper answered 15/10, 2014 at 6:53 Comment(0)
E
0

Based on the answer here Accessing the web page's HTTP Headers in JavaScript I built the following script to get the browser language:

var req = new XMLHttpRequest();
req.open('GET', document.location, false);
req.send(null);
var headers = req.getAllResponseHeaders().toLowerCase();
var contentLanguage = headers.match( /^content-language\:(.*)$/gm );
if(contentLanguage[0]) {
    return contentLanguage[0].split(":")[1].trim().toUpperCase();
}
Epifaniaepifano answered 17/11, 2014 at 8:48 Comment(0)
A
0

If you are using ASP .NET MVC and you want to get the Accepted-Languages header from JavaScript then here is a workaround example that does not involve any asynchronous requests.

In your .cshtml file, store the header securely in a div's data- attribute:

<div data-languages="@Json.Encode(HttpContext.Current.Request.UserLanguages)"></div>

Then your JavaScript code can access the info, e.g. using JQuery:

<script type="text/javascript">
$('[data-languages]').each(function () {
    var languages = $(this).data("languages");
    for (var i = 0; i < languages.length; i++) {
        var regex = /[-;]/;
        console.log(languages[i].split(regex)[0]);
    }
});
</script>

Of course you can use a similar approach with other server technologies as others have mentioned.

Angeliaangelic answered 14/8, 2015 at 12:44 Comment(0)
A
0

For who are looking for Java Server solution

Here is RestEasy

@GET
@Path("/preference-language")
@Consumes({"application/json", "application/xml"})
@Produces({"application/json", "application/xml"})
public Response getUserLanguagePreference(@Context HttpHeaders headers) {
    return Response.status(200)
            .entity(headers.getAcceptableLanguages().get(0))
            .build();
}
Apology answered 22/12, 2015 at 3:47 Comment(0)
S
0

i had a diffrent approach, this might help someone in the future:

the customer wanted a page where you can swap languages. i needed to format numbers by that setting (not the browser setting / not by any predefined setting)

so i set an initial setting depending on the config settings (i18n)

$clang = $this->Session->read('Config.language');
echo "<script type='text/javascript'>var clang = '$clang'</script>";

later in the script i used a function to determine what numberformating i need

function getLangsettings(){
  if(typeof clang === 'undefined') clang = navigator.language;
  //console.log(clang);
  switch(clang){
    case 'de':
    case 'de-de':
        return {precision : 2, thousand : ".", decimal : ","}
    case 'en':
    case 'en-gb':
    default:
        return {precision : 2, thousand : ",", decimal : "."}
  }
}

so i used the set language of the page and as a fallback i used the browser settings.

which should be helpfull for testing purposes aswell.

depending on your customers you might not need that settings.

Supra answered 21/3, 2016 at 11:22 Comment(0)
P
0

I have a hack that I think uses very little code and is quite reliable.

Put your site's files in a subdirectory. SSL into your server and create symlinks to that subdirectory where your files are stored that indicate your languages.

Something like this:

ln -s /var/www/yourhtml /var/www/en
ln -s /var/www/yourhtml /var/www/sp
ln -s /var/www/yourhtml /var/www/it

Use your web server to read HTTP_ACCEPT_LANGUAGE and redirect to these "different subdirectories" according to the language value it provides.

Now you can use Javascript's window.location.href to get your url and use it in conditionals to reliably identify the preferred language.

url_string = window.location.href;
if (url_string = "http://yoursite.com/it/index.html") {
    document.getElementById("page-wrapper").className = "italian";
}
Posehn answered 24/1, 2017 at 16:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.