Skip to content

Aquent | DEV6

Generic selectors
Exact matches only
Search in title
Search in content
Search in posts
Search in pages

The Language API is Broken in Safari for iOS

Written by: Chad Upton

This issue has been resolved in iOS 14.0. We’ll leave the article here for anyone who might need it for historical purposes.


Obviously, not everyone speaks or reads the same language, so it’s important for web applications to detect the user’s language preference and render the application in that language when appropriate.

Now, it’s important to understand that some languages have regional differences too. For example, if you speak French, do you speak French from Canada or French from France? Portuguese from Portugal, or Brazil? Spanish from Spain, or Mexico? You get the idea.

To get this right, all major browsers support a JavaScript API that provides the user’s preferred language and region — or at least they used to.

A couple of months ago, an update to Safari on iOS (and macOS) broke this API. I’m not sure exactly when it was broken, but based on our automated JavaScript error logging, it was first noticed in these releases:

iOS Version: 13.4.1 (April 7, 2020)

macOS Safari Version: 13.1 (March 24, 2020)

You see, when you query navigator.language you’d normally get something like: en-US

The “en” means English (language) and the “US” means United States (locale).

But when you query navigator.language in iOS right now, you just get the language: en.

At first, I wasn’t sure if this was a bug, or if it was intentional. Since it potentially reveals the user’s country of origin and can act as one more element in a user’s digital fingerprint, I thought it was possible they intentionally removed the locale for privacy reasons. Losing the locale would be unfortunate since the locale is also important for setting the type of punctuation, currency and other regional differences that might be appropriate for that user.

I was hoping it was just a bug, so I filed a bug report with Apple using Feedback Assistant. I still haven’t heard anything, but the 13.1.1 update to Safari for macOS has resolved this issue. A couple of iOS releases have gone by without a fix, but I’m hoping that the upcoming 13.6 release will address this too.

Since it seems like they’re addressing this issue, it’s not a major concern anymore. However, I thought it was important to document this issue for historical purposes. I haven’t seen this issue mentioned anywhere else, and this might be helpful for those of you in the future who might be trying to determine why navigator.language was failing in your application.

Oh, one more thing… When your application is reading the locale, you should always force the value to uppercase (or lowercase if that makes the most sense for your implementation). But definitely force it to one or the other because Safari for macOS returns the locale in lowercase while every other browser (and Safari for iOS usually) returns the locale in uppercase.