Using Contentful for multi-language publishing

The ability to show your users content based on their geographical location or language preferences is essential for modern websites and mobile apps. If you know your user’s location, you can deliver content targeted specifically for their area and likely interests. So take advantage of today’s geolocation-friendly technology and use it to craft a better user experience!

These days users in North America expect to be able to see content in English, even if it comes from a German-based website. When browsing an online retailer, users would prefer to see products that can be to be shipped to their home. Even your marketing material might change depending on your user’s location; certain images appeal more to Americans than to Canadians, regardless of the close geographical proximity.

Localized publishing made easy

Within Contentful, each of these languages or geographical regions is an individual Locale. Our localization feature makes multi-language publishing simple by giving you an extra field for each locale that you enable. This allows you to store only one version of your content, what we call an entry, instead of having separate versions for each language.


An entry with localized fields

Configuring locales

To begin setting up your locales, navigate to Locales under your space settings. You will always see the default locale that you chose when you created the space. Hit the blue Add Locale button and select one of the many locales on our list. The list is quite extensive, but if you don’t see what you’re looking for (Klingon, perhaps?), you can always add your own via our Content Management API.


Built-in language options

Locale settings

Next you will be able to configure the locale’s settings. Your default locale will always be listed first; this is the locale that will be used when other locale fields are empty. You can change the default locale by clicking on it and selecting a new language from the menu.


Locale settings menu

You can also enable or disable the locale in the API response and in the entry editor. If you disable the locale in the response, the content will still be visible and editable in the entry editor, but will not be delivered to your application. Disabling in the entry editor means the locale fields will not be visible or editable, but the content will continue to be delivered via the API.

Optional locales

It may be the case that you want the default locale to be required but the other locales to be optional. For example, if you want to ensure that the English locale fields are always filled out but it’s okay to publish the entry with the Chinese field empty. In that case, remember to select the Allow empty fields for this locale checkbox.

This is a particularly useful setting for working with multiple translators. Is your Spanish translator a bit quicker than your French translator? If the Spanish market is more important to your business, you can publish the entry first in Spanish and let the French catch up later.

Enabling locales

After adding a new locale and adjusting the settings, you must enable it. Locales are enabled on a per-space and per-field basis, and you can also toggle the visibility of the locale fields within your entries. This sounds complicated but it’s really a good thing! It gives you more control over what content is localized and when.

Enabling on fields

First open the content type of an entry that you would like to be localized. Go into the field settings for each field you need localized and check the "enable localization of this field" box. You will need to do this for each field, but again, this is to give you extra control over which fields are localized.


Making the title of an entry translatable into multiple languages.

Enabling in the entry editor

Another level of granularity is the ability to hide/show locales at the entry level. Say you have three locales enabled for your field but for your work you personally only need to see two of them. You can simply hide the locale fields of the language you don't need using the Translations controls in the sidebar! Keep in mind that this setting affects all of your entries and does not control what other users see.


Hide/show locale fields using the Translations options.

Managing translators

If you’re publishing content in more than one language, chances are you’ve got a trusted team of translators. However, as much as you trust your team, you might still want to limit their editing permissions within Contentful. You wouldn’t want your Italian translator to accidentally write “Ciao, bella!” in the field for Japanese. Control which locales your translator can work with using our custom roles and permissions feature. With this advanced feature you can set granular permissions for your members, including restricting their actions to one or more locales.


Assign this role to a translator, and he'll only be able to edit content in German

If you’re already working with a translation management system, you might be able to integrate it with Contentful. In theory, any platform with an API can interact with Contentful, it just takes some code work. To learn more, take a look at our API documentation.

Working with many locales

By now you might be wondering if having all of those extra locale fields becomes a problem when working with a large number of locales. The truth is, yes, if your entry requires many dozens of locales, it can be disruptive to your authoring environment. That being said, it definitely doesn’t stop our customers. Specialized Bicycle Components, for example, is using Contentful to publish in over 30 languages! There are ways to make working with many locales easier.

Control content visibility

First, you should make sure your translators know how to hide/show locales, as described above. This way they can limit the number of locales visible to them in the entry editor, which not only makes things more readable but also improves performance of the web app.

Another option is to use our roles and permissions feature to limit your editors to only editing or viewing certain locales. This way, when they open an entry in the editor, they would only see a few of your localized fields at a time. Does your Spanish translator really need to see the German version? Probably not. Make their life easier by only showing them the locales they really need to work with.


An entry as seen by a user with full locale access


An entry as seen by a user with limit locale access

Tap into localized assets

Much as you can add localized content to your entries, you can create localized versions of your assets. The localization option extends to both - asset title and description, and the actual binary file. This allows you to use a single asset named flag, but display appropriate flags in different languages. Or you could re-use the same image, but add captions in multiple languages. In either case, you only need to add an asset to your entry once and from there on, our API will treat it according to the localization rules set out above.

Localized assets

An example of a localized asset named Flag

Handling the missing translations

Now let's take a look at more advanced scenarios. The biggest problem editorial teams face is how to handle the missing translations for particular languages in a scalable and elegant way. To help you deal with that, you can turn to configuring custom fallback locales and understand the technical implications of leaving localized fields empty.

Custom fallback locales

By default, whenever Contentful comes across an entry with a missing localized content, it will revert to a default fallback locale (e.g. English). Alas, English is not always the most appropriate language to default to, because Swiss visitors usually prefer to see a German or French version of your website, while Argentinians are more comfortable with accessing content in standard Spanish. To accommodate the needs of your audience, you can define a custom fallback logic for your locales.

To construct a fallback tree, start with the lowest branch, say, Swiss German (locale code de-CH) and pick standard German (de-DE) as its fallback locale. You can repeat the same step for the Austrian German (de-AT), Luxembourgish German (de-LU), and Belgian German (de-BE), provided you actively use these locales. For the standard German, you can repeat the step and add another language as its fallback, or you can specify that no further fallback should be invoked.

Custom fallback locales

With standard German (de-DE) as a fallback locale for Swiss German (de-CH), website visitors will see German content where the Swiss values are missing

To get the hang of it, imagine we have an entry with three locales - Spanish (Mexico)(es-MX), Spanish (Spain)(es-ES), and English (US)(en-US). The fallback logic is defined as (es-MX) > (es-ES) > (en-US) and here is how API would respond in different scenarios:

CMA call CDA call for locale es-MX Fallback logic
"title": {
"en-US": "Hello NYC"
"title": "Hello NYC" Falls back to es-ES which falls back to en-US which is "Hello NYC"
"title": {
"en-US": "Hello NYC",
"es-ES": "Hola Barcelona"
"title": "Hola Barcelona" Falls back to es-ES which is "Hola Barcelona"
"title": {
"en-US": "Hello NYC",
"es-ES": "Hola Barcelona",
"es-MX": "Hola Mexico"
"title": "Hola Mexico" No fallback implied, returning es-MX value which is “Hola Mexico”

When the same setup is modified to stop the fallback at (es-ES), the API output will behave as follows:

CMA call CDA call for locale es-MX Fallback logic
"title": {
"en-US": "Hello NYC"
  No “title” field returned in the payload since no value present and the fallback chain stops at es-ES.

Remember that once you designate a particular locale as a part of a fallback chain, you cannot disable it in a CDA response. We also didn't want you to accidentally get stuck in an infinite loop, so the dropdown for a new locale will automatically exclude all the locales already used in the current fallback chain.

Empty fields

Another important nuance to master when handling edge cases in your web app is to understand when the CDA uses the defined fallback locale to return a value. The CDA fallback chain kicks in only when no value is defined for a given locale. To use the previous example, if es-MX locale has no value, then the CDA looks into es-ES. But what do we mean exactly by "no value"? Programmers know that this can take many shapes from undefined to "" to null.

Whenever you interact with Contentful via the CMA, we follow the 'what you set is what you get' rule, meaning that setting either a null or an empty string value for the es-MX locale, will return this same value in the CDA payload and prevent the fallback mechanism from happening. By contrast, not setting any value for the locale will lead to the CDA returning the value of a fallback locale.

The Web Application takes a more conservative approach towards handling empty values. Whenever you have an entry with an empty field, it will trigger the fallback chain or, to put it in technical terms, editors cannot set a field value to "" or null from within the web app. This ensures a smoother editing experience and avoids accidental edits leading to undesired behavior. Also, note that any value set using the CMA will be preserved by the Web Application unless an editor edits the field.

Need localization?

Click here to see if your subscription plan includes localization the feature. Interested in custom roles and permissions? Reach out to our Enterprise team!

This page was updated on Sep 7, 2016 to include the description of the newly released features.

Discover more Contentful.

If you enjoyed this article, you might like our product as well.

What our product does

Take a look at the API capabilities, delivery infrastructure and friendly editing environment.
See features

What our clients built

From apps and sites to digital signage and iBeacon campaigns — we deliver content everywhere.
See real-life examples