Lots of websites get tripped up trying to offer users a choice of language. But a few simple steps can ensure your users get exactly the language they want.
I have the dubious honor in my social circle of being one of the few who speaks only one language fluently. Fortunately for me the language I speak is a pretty popular one, but when I visit websites when I'm overseas, even ones I use a lot, it's surprising how often they suddenly think I want the site in Spanish, Japanese or Polish. This is one of a bunch of things websites often get wrong when designing a language-localized experience.
We can group these language-switching fails into roughly three categories: bad assumptions, poor labeling, and unintuitive persistence. Let's address these and then consider a checklist of good practices for language switchers (and also some ideas for how to use edge computing to make this easier!).
- Bad assumptions: the most common mistakes
- Poor labeling: avoid red flags!
- Broken persistence: what not to forget
- Edge computing to the rescue! (so predictable but I like my job etc.)
Bad assumptions
A user's physical location is not the best indicator of the language they understand. It's correlated: it's certainly true that a user based in Mexico is much more likely to speak Spanish than a user in Finland. But this logic results in a really poor experience when people are traveling away from their home country. Using the Accept-Language
header (which communicates the user's device system locale) is a much better way to figure out what language to select.
For retailers, it's also risky to assume that delivery location, language and currency should all change together. If I want to buy a gift for a friend overseas, I might want a foreign delivery location but still shop in my native language and currency.
What if someone migrates to a new country but still prefers their native language? Now you might have a currency and location that seem to match but with a language that doesn't fit. The more flexibility you can build into your system design, the less convoluted the solutions you'll have to come up with to deal with these edge cases.
Google Flights offers a masterclass in doing this correctly - language preference is detected from browser locale, location from your IP address, and currency synced to location - but all are independently adjustable:
In summary:
- Don't assume that the user wants the predominant language of the country they are physically located in. Use browser locale in preference to the user's physical location when choosing a language automatically.
- Don't assume that currency, language and delivery location are all "in sync"
Poor labeling
Flags are a somewhat controversial way of representing language choice. Neilsen, a UX consultancy, found that users do associate their country's flag with their language, but where a language is spoken in multiple countries, this can be quite a political minefield.
My favorite example of a bizarrely labeled language switcher from a German sofa company.
It's not completely wrong to associate languages with places. The English spoken in the UK is clearly not (entirely) the same as that spoken in the US, and the commonly used IETF language tags standard uses this as the basis for classifying language variants: en-GB
, and en-US
, for example.
As with so many standards that attempt to classify and group human behavior, some compromise is needed. Most correctly you might say that en-IN
is "a dialect of the English language which has its cultural center of gravity in India" but how exactly you define that dialect and who gets to do so is highly debatable, and obviously any variant of any language could be spoken in any physical location in the world.
So, using flags can be a nice experience for users but is hard to make work across a large user population unless you have invested in multiple variants.
Businesses clearly need to be pragmatic, and will invest time and money only where there is a market for their products or services. It's actually quite uncommon for websites (except the very largest) to bother providing services in multiple variants of the same language, and where there is a link between locations and languages, it's often more likely to be because the business has a local version of the entire site, which is then offered in whatever languages are deemed to be relevant to that location.
Booking.com doesn't have regional sites, and uses flags for language choice, but is able to offer the correct regional variants of the languages that match the flags (check out the multiple English, Spanish and Portuguese variants here):
Great job Booking.com team!
Now consider IKEA, which unlike Booking.com is selling physical products that vary between countries, and therefore they do have regional sites each offered in a different selection of languages.
IKEA Portugal, for example, offers Portuguese and English, but doesn't specify which variant of either of those they are using ('pt/en' doesn't mean "the variant of English spoken in Portugal", but rather "the Portugal website, rendered in English"):
That's a pretty common pattern for sites whose product offering varies between countries. Here's Storytel's Brazil site, which is only available in Portuguese (presumably pt-BR
?):
In summary, disassociating language and location is pretty hard and ultimately the most practical solution depends on to what extent your product or service is different in different markets.
The other labeling issue I find interesting is the icon or symbol used to indicate that language selection is available. The most common choices are a globe, some kind of specific "languages" icon, the name of the currently selected language, or a list of available languages with the current one highlighted.
The Language Icon project has been trying to standardize this for 15 years, and today doesn't enjoy very much traction, while most major global sites seem to have adopted a globe. The advantage of the big ol' list of languages approach (normally in the footer) is that if I see a wall of text I don't understand, I can press CMD+F and search the page for the word "English" and find the link to the English version.
The worst offense here is to have a menu option somewhere called "Change language". Any English speaker who has ever been pranked by friends who changed their phone's UI to Korean will be familiar with the challenges this presents.
Labeling is really important. Some things to bear in mind:
- Write the names of languages in the language itself. Offer "Deutsch", not "German"
- Don't expose users to labels designed for computers. No-one should have to know what "DE" means.
- Make clear the distinction between "service location" and "language region"
- Use a globe symbol for a language selector
- Consider listing available languages somewhere on the page
Unintuitive persistence
The final horseman of the language apocalypse is the challenge of persisting language choices, and when to do so. Users have an annoying tendency to log out, use more than one device, and even send links to friends and family who might prefer different languages!
A great example of this problem happens if you are visiting a friend overseas and they send you a link to a Google Maps location where they want to meet you. Odds are, you'll click that link and it will display Google Maps in your friend's language, not yours.
On the face of it that seems odd because in principle the way the web works is that the same URL should be available in multiple languages and the server gives you the one that matches your Accept-Language
preference. However, this idealized idea of 'content negotiation' is rarely used in its purest form on the web, not just because of technical headaches but because it sometimes isn't actually the right experience.
On a news / long-form content site, if content is available in multiple languages, it's rarely exactly equivalent. I might send the French version of an article to a friend who normally prefers English, because it reads better in French, or includes content not available in the English version.
Sharing is a minefield. But problems with persistence can arise even when just dealing with one user. What if a user registers for an account on your site, and has never made an explicit language selection, but then changes their device language. Since they have an account, you might feel that in this situation the account settings have taken over from automatic selection, but since they never made an explicit choice, shouldn't we still be led by their browser locale?
This is where we need to make smart decisions about how to persist language choice, and the hierarchy of precedence for the different language signals. I prefer the following principles:
- The "user preference" is an explicit choice saved on your account, or the
Accept-Language
header if there's no saved preference. - A language specific URL overrides the user preference, but an inconsistency between the two should be signalled to the user.
For example, if a friend sends me a link to www.example.com
and I've never been there before, my friend might have seen it in French but I'd get it in English, because of Accept-Language
.
However, if they sent me a link to www.example.com/fr/products/123
, then I'd see the page in French, with an alert asking me (in English) if I want to switch to English.
Edge computing to the rescue
I'm obviously now going to tell you how Fastly is the answer to all your language challenges, right? Well, it does actually make a lot of sense to manage aspects of language selection at the edge. One of the most important things to do is to normalize the Accept-Language
value. In Fastly VCL you can do that like this:
set req.http.Accept-Language = accept.language_lookup("en:de:fr:nl", "de", req.http.Accept-Language);
This will turn a value such as en-GB,en-US;q=0.9,en;q=0.8
into en
, and means that you can store far fewer versions of your pages.
Also consider redirecting users to a language-specific URL when they arrive at your homepage. A custom VCL subroutine will do the trick here:
sub locale_redirect {
declare local var.urlLocale STRING;
declare local var.prefLocale STRING;
set var.urlLocale = if (req.url.path ~ "^/(en|de|fr|nl)/", re.group.1, "");
set var.prefLocale = if (
req.http.cookie:lang,
req.http.cookie:lang,
req.http.Accept-Language
);
if (var.urlLocale == "" && var.prefLocale != "") {
error 600 var.prefLocale;
}
}
Whatever you do at the edge, I hope some of this helps you build more insightful, more intuitive language-sensitive experiences for your users!
Also tell us what you build, at community.fastly.com.