Full disclosure: I was born and live in the USA, American English is my native language, and I spend USD every day. However, I work with customers in 18 countries and regions on five continents, and the list is getting bigger all the time.

Operating a business in the global market is not as trivial as it might seem, if you’ve never seen it through. Everyone not only speaks different languages and has different currencies (not to mention driving on the different sides of the road), but they also have different cultural norms. In many situations, we can merely provide raw values for dates and currency and avoid formatting. However, when content includes localizable information, especially dates and currencies, display formatting needs to be sensitive to the localized culture.

If you’re considering making the jump off of your own soil to the rest of the globe, hopefully this will give you some insights.

Terms

Let’s go over some terms you might have heard in regards to these topics:

Internationalization (I18n) means structuring applications in a way that makes it possible for them to be localized.

means structuring applications in a way that makes it possible for them to be localized. Localization (L10n) means making an application work for a particular market, such as French-speaking Canadians.

means making an application work for a particular market, such as French-speaking Canadians. Native Language Support (NLS) essentially describes the translation of content into the correct language and locale.

Example of the problem

Now a practical example of localization issues when we change the parameters on a simple piece of text:

English, USA, US Dollars – “Price: $99.00, Delivery: 8/1/2013 8:15:00 PM”

Spanish, Mexico, Mexican Pesos – “Precio: $1216.28, Entrega: 1/8/2013 20:15:00”

Note the differences in language, currency, and date format.

In addition, there are particular issues in ambiguity with currency symbols, especially when operating in foreign markets where symbols could potentially collide with local currency.

English, Canada, Canadian Dollars – “Price: CA$1.00, Delivery: 2013-08-01 8:15:00 PM”

English, Canada, Peruvian Pesos – “Price: 464.34 CLP, Delivery: 2013-08-01 8:15:00 PM”

Note that currency symbols changed, as well as the position of the currency. However there are no changes to language or date formatting in this scenario.

ISO Standards

In order to formulate a strategy, it’s best to know what the international standards are for specifying globalization parameters. Language, country and currency are most often specified.

Localization parameters

Specifying localization parameters can be done via HTTP headers, query string, or potentially in content. Query string approaches are inadvisable in HTTP-based APIs (dare I say REST), as this implies a ‘query’, and in some rare cases can affect GET caching. Headers typically work quite nicely as URIs are unaffected and HTTP actually gives us some of this built-in.

HTTP Headers

Accept-Language and Content-Language headers

Armed with our knowledge of language and country codes, we can utilize the built-in header in HTTP, “Accept-Language”. This works in the same content negotiation pattern as “Accept” and “Content-Type”, except it utilizes Language Tags, “where any two-letter primary-tag is an ISO-639 language abbreviation and any two-letter initial subtag is an ISO-3166 country code”, as administered by IANA.

The best description of this I’ve seen worked through is in one my favorite books, RESTful Web Services Cookbook, Section 7.3:

The protocol for language negotiation is similar to media type negotiation. The client

expresses its intent by supplying an Accept-Language header with acceptable languages

and their q header parameter values, and the server decides which one to use for the

response.



# Request

GET /movie/gone_with_the_wind HTTP/1.1

Host: www.example.org

Accept-Language: en,en-US,fr;q=0.6

{noformat}

{noformat}

# Response

HTTP/1.1 200 OK

Content-Type: application/xml;charset=UTF-8

Content-Language: en

Vary: Accept-Language 1936

…

This approach is best suited when representations in different languages differ only in

terms of the language used for any human-readable text in the representation, as in the

following representation:



# Request

GET /movie/gone_with_the_wind HTTP/1.1

Host: www.example.org

Accept-Language: en,en-US,fr;q=0.6



Non-standard HTTP headers

For currency, the HTTP spec does not provide us with any standards. As such, we are left to define custom headers. Prefixing the header name with “X-” signals to many servers that this should pass through, and often prevents collision with standard headers.

“X-Currency” is often a great choice for setting currency in “Accept” for the request, and consequently the same thing in the “Content-Type” in the Request (for POST/PUT) and Response.

The key to educating our API consumers is that the ISO 4217 standard provides us with various means to communicate currencies. As part of this spec, 2-3 character codes can indicate specific currencies (great for input/request), and within any formatted currency values, there are also currency symbols defined (useful in output/response).

UPDATE: As was pointed out to me by John Sheehan, and readers on Hackernews, the “X-” has been deprecated in RFC 6648, also more detail here. A more appropriate value might be “-Currency”. It also might be better to use “Accept-Currency” on request, and “Content-Currency” on response.

To continue with the example above, but for currencies:

# Request

GET /movie/gone_with_the_wind HTTP/1.1

Host: www.example.org

X-Currency: USD

Note that the three-letter currency code should be utilized here. This helps dictate the formatting of any currency in content, such as:

Currency symbol: e.g. “$” US Dollars, “€” Euro

Decimals and commas: e.g. “1,000,000.00” in USA, “1 234,56” in Portugal

Symbol alignment: e.g. “$1,000,000.00” in USA, “1 234,56$” in Portugal (same as above but with symbols, note right alignment for Portugal)

Summary

The only real support we get from HTTP is “Accept-Language” and “Content-Language”. For currency, we’re often forced to provide an artificial standard to our API users. The good news is, by following the established ISO 4217 standard, currencies are very crisply communicated, both in terms of API input and output.

Language, country, and currency typically describe all the globalization parameters. Depending on your web strategy, there could be other parameters to consider. Utilize “X-“, and consider including your company/project name in order to avoid conflict with existing HTTP standards or other companies’ usages.

Learn the existing international standards for language, country, currency, and dates. Avoid formatted outputs as much as possible. Sticking to these fundamentals should keep you out of trouble.

Please join in the discussion on this article over on Hacker News and reddit.