Locales

Locales allow you to define translatable content for assets and entries. A locale includes the following properties:

  • name: A human readable identifier for a locale. For example, ‘British English’.

  • code: An identifier used to differentiate translated content in API responses. For example, ‘en-GB’.

  • fallbackCode: The code of the locale to use if there is no translated content for the requested locale. For example, en-US. You can set it to null if you don’t want a default locale. This can only be set via the API, and not with the web app or client libraries.

Locale collection

Get all locales of a space

The locales endpoint returns a list of all created locales. One will have the flag default set to true and is the locale used in the CDA, and you specified no other locale in the request.

Locale-based publishing

Use the X-Contentful-Locale-Based-Publishing request header to opt in to locale-based publishing.

$curl -i \
> -H "Authorization: Bearer $TOKEN" \
> -H "X-Contentful-Locale-Based-Publishing: true" \
> "https://cdn.contentful.com/spaces/$SPACE/environments/$ENV/entries/$entry1?locale=de-DE"

When this header is present, only published locales will be returned. Publishing status is determined from entry.sys.fieldStatus in the Content Management API.

The header doesn’t apply to Content Preview API. The CPA silently ignores it and returns content regardless of locale publishing status.

Behavior

  • The header applies to both Entry and Asset types.

  • For entry-level publishing, enabling this header doesn’t change the existing response behavior — the content will be returned as previously without the header.

  • Fallback locales are not used to determine publishing status, but only for content resolution. If a requested locale is unpublished, a published fallback locale doesn’t make it visible in the response.

  • When a locale is added to a space, affected entries must be republished before that locale appears in CDA responses. Republish the locale where locale-based publishing is available, or republish the entry for entry-level publishing.

Locale-based publishing behavior is opt-in during rollout. Contentful plans to enable it by default, so we recommend adopting and testing this header before the default behavior changes.

Examples

Request a published and draft locale

The following Content Management API entry has one published locale and one draft locale:

1{
2 "sys": {
3 "id": "productPage",
4 "type": "Entry",
5 "fieldStatus": {
6 "*": {
7 "en-US": "published",
8 "de-DE": "draft"
9 }
10 }
11 },
12 "fields": {
13 "title": {
14 "en-US": "Product page",
15 "de-DE": "Produktseite"
16 }
17 }
18}

When the locale-based publishing header is enabled, a CDA request for the published en-US locale returns the entry:

$curl -i "https://cdn.contentful.com/spaces/{space_id}/environments/{environment_id}/entries/productPage?locale=en-US" \
> -H "Authorization: Bearer {access_token}" \
> -H "X-Contentful-Locale-Based-Publishing: true"
1HTTP/1.1 200 OK
1{
2 "sys": {
3 "id": "productPage",
4 "type": "Entry",
5 "locale": "en-US"
6 },
7 "fields": {
8 "title": "Product page"
9 }
10}

A CDA request for the draft de-DE locale does not return the entry:

$curl -i "https://cdn.contentful.com/spaces/{space_id}/environments/{environment_id}/entries/productPage?locale=de-DE" \
> -H "Authorization: Bearer {access_token}" \
> -H "X-Contentful-Locale-Based-Publishing: true"
1HTTP/1.1 404 Not Found

Request unpublished and changed locales

The following example space has three enabled locales: en-US, de-DE, and nl-NL.

entry1 is published only in en-US. After publishing, entry1 was edited again in en-US, so its en-US status is changed. The de-DE and nl-NL locales are not published for entry1.

entry2 is published in both en-US and de-DE. This doesn’t affect which locales are visible for entry1.

1[
2 {
3 "sys": {
4 "id": "entry1",
5 "type": "Entry",
6 "fieldStatus": {
7 "*": {
8 "en-US": "changed",
9 "de-DE": "draft",
10 "nl-NL": "draft"
11 }
12 }
13 },
14 "fields": {
15 "title": {
16 "en-US": "Product page draft edit",
17 "de-DE": "Produktseite",
18 "nl-NL": "Productpagina"
19 }
20 }
21 },
22 {
23 "sys": {
24 "id": "entry2",
25 "type": "Entry",
26 "fieldStatus": {
27 "*": {
28 "en-US": "published",
29 "de-DE": "published",
30 "nl-NL": "draft"
31 }
32 }
33 },
34 "fields": {
35 "title": {
36 "en-US": "Category page",
37 "de-DE": "Kategorieseite",
38 "nl-NL": "Categoriepagina"
39 }
40 }
41 }
42]

Fetching an unpublished locale for entry1 returns a 404 response:

1GET /spaces/{space_id}/environments/{environment_id}/entries/entry1?locale=de-DE HTTP/1.1
2Host: cdn.contentful.com
3Authorization: Bearer {access_token}
4X-Contentful-Locale-Based-Publishing: true
1HTTP/1.1 404 Not Found

Fetching another unpublished locale for entry1 also returns a 404 response:

1GET /spaces/{space_id}/environments/{environment_id}/entries/entry1?locale=nl-NL HTTP/1.1
2Host: cdn.contentful.com
3Authorization: Bearer {access_token}
4X-Contentful-Locale-Based-Publishing: true
1HTTP/1.1 404 Not Found

Fetching the published en-US locale for entry1 returns a 200 response. Because the locale has unpublished changes, the CDA response contains the last published value, not the post-publish edit.

1GET /spaces/{space_id}/environments/{environment_id}/entries/entry1?locale=en-US HTTP/1.1
2Host: cdn.contentful.com
3Authorization: Bearer {access_token}
4X-Contentful-Locale-Based-Publishing: true
1HTTP/1.1 200 OK
1{
2 "sys": {
3 "id": "entry1",
4 "type": "Entry",
5 "locale": "en-US"
6 },
7 "fields": {
8 "title": "Product page"
9 }
10}