Disclaimer: This website requires Please enable JavaScript in your browser settings for the best experience.

Dev guideRecipesAPI ReferenceChangelog
Dev guideRecipesUser GuidesNuGetDev CommunityOptimizely AcademySubmit a ticketLog In
Dev guide

Sync fallback language versions

Describes how to sync and query fallback language versions in Optimizely Graph

Optimizely Graph supports fallback languages, allowing queries to automatically return content from an alternative language when localized content is unavailable. This enables consistent content delivery across locales without additional query logic.

To use fallback languages with Optimizely Graph, prepare your content types and index content correctly.

Before you begin

Ensure the following:

  • You use the next preset.
  • Your index uses useTypedFieldNames=true.
  • Your project includes the locales you want to support.
  • You have access to sync content to Optimizely Graph.

This example uses three locales: en, sv, and de.

Prepare content types

In this example, we will prepare some simple content types to demonstrate how fallback languages feature works.
Fallback languages only work with next preset.

The example is written with useTypedFieldNames=true.

The example has three locales en, sv and de.

{
  "label": "Test fallback",
  "preset": "next",
  "useTypedFieldNames": true,
  "description": "These content types are to demonstrate how to use fallback language feature",
  "languages": [
    "en",
    "sv",
    "de"
  ],
  "links": {},
  "contentTypes": {
    "Article": {
      "contentType": [],
      "properties": {
        "Title": {
          "type": "String"
        },
        "Description": {
          "type": "String"
        }
      }
    }
  },
  "propertyTypes": {
  }
}

You can create the indices using Swagger, Postman, curl, or any tools that can make HTTP requests. The following example uses curl with Basic authentication using Turnstile HMAC key pair. You can run this on Linux, macOS, or Windows Subsystem for Linux (WSL).

Save your content types to contenttypes.json and run the following

curl --location --request PUT 'https://cg.optimizely.com/api/content/v3/types?id=default' \
--header 'Content-Type: application/json' \
--header 'Authorization: Basic <Token>' \
--data @content_type.json

Check Basic auth on how to create the token.

Prepare contents for fallback feature

When indexing fallback contents, make sure your contents have the following fields

  • _metadata.locale: the language the content is in, for example en.
  • _metadata.fallbackForLocale: the locales that the content is the fallback version for, in this example sv.
  • _metadata.status: Must be set to Published so it is queryable using single key.
  • _metadata.types: set to Article.
  • __typename: set to Article.
  • _rbac: Must be set to r:Everyone:Read to be queryable using single key.

Indexed content scenarios

This example indexes three content items:

  • English (main content)
  • Swedish (fallback to English)
  • German (main content)

Main English content

The main version must:

  • Set _metadata.locale to en.
  • Omit _metadata.fallbackForLocale.
  • Index to the en locale
{"index":{"_id":"12345_en_Published","language_routing":"en"}}
{
    "ContentType": "Article",
    "Title$$String": "Germany", 
    "Description$$String": "Germany is a country in Europe",
    "_metadata": {
        "locale": "en",
        "types": ["Article"],
        "status": "Published"
    },
    "_rbac": "r:Everyone:Read",
    "__typename": "Article"
}

Swedish fallback content

Fallback content must:

  • Set _metadata.locale to the actual content language (en)
  • Set _metadata.fallbackForLocale to sv.
  • Index to the sv locale.
{"index":{"_id":"12345_sv_Published","language_routing":"sv"}}
{
    "ContentType": "Article",
    "Title$$String": "Germany", 
    "Description$$String": "Germany is a country in Europe",
    "_metadata": {
        "locale": "en",
        "fallbackForLocale": "sv",
        "types": ["Article"],
        "status": "Published"
    },
    "_rbac": "r:Everyone:Read",
    "__typename": "Article"
}

Main German content

The main German version must:

  • Set _metadata.locale to de.
  • Omit _metadata.fallbackForLocale.
  • Index to the de locale.
{"index":{"_id":"12345_de_Published","language_routing":"de"}}
{
    "ContentType": "Article",
    "Title$$String": "Deutschland", 
    "Description$$String": "Deutschland ist ein Land in Europa",
    "_metadata": {
        "locale": "de",
        "types": ["Article"],
        "status": "Published"
    },
    "_rbac": "r:Everyone:Read",
    "__typename": "Article"
}

The resulting NDJson for all three contents will be as follows:

{"index":{"_id":"12345_en_Published","language_routing":"en"}}
{"ContentType":"Article","Title$$String":"Germany","Description$$String":"Germany is a country in Europe","_metadata":{"locale":"en","types":["Article"],"status":"Published"},"_rbac":"r:Everyone:Read","__typename":"Article"}
{"index":{"_id":"12345_sv_Published","language_routing":"sv"}}
{"ContentType":"Article","Title$$String":"Germany","Description$$String":"Germany is a country in Europe","_metadata":{"locale":"en","fallbackForLocale":"sv","types":["Article"],"status":"Published"},"_rbac":"r:Everyone:Read","__typename":"Article"}
{"index":{"_id":"12345_de_Published","language_routing":"de"}}
{"ContentType":"Article","Title$$String":"Deutschland","Description$$String":"Deutschland ist ein Land in Europa","_metadata":{"locale":"de","types":["Article"],"status":"Published"},"_rbac":"r:Everyone:Read","__typename":"Article"}

Sync content to Optimizely Graph

Sync all content using the NDJSON format:

curl --location 'https://cg.optimizely.com/api/content/v2/data' \
--header 'Content-Type: application/x-ndjson' \
--header 'Authorization: Basic <Token>' \
--data '{"index":{"_id":"12345_en_Published","language_routing":"en"}}
{"ContentType":"Article","Title$$String":"Germany","Description$$String":"Germany is a country in Europe","_metadata":{"locale":"en","types":["Article"],"status":"Published"},"_rbac":"r:Everyone:Read","__typename":"Article"}
{"index":{"_id":"12345_sv_Published","language_routing":"sv"}}
{"ContentType":"Article","Title$$String":"Germany","Description$$String":"Germany is a country in Europe","_metadata":{"locale":"en","fallbackForLocale":"sv","types":["Article"],"status":"Published"},"_rbac":"r:Everyone:Read","__typename":"Article"}
{"index":{"_id":"12345_de_Published","language_routing":"de"}}
{"ContentType":"Article","Title$$String":"Deutschland","Description$$String":"Deutschland ist ein Land in Europa","_metadata":{"locale":"de","types":["Article"],"status":"Published"},"_rbac":"r:Everyone:Read","__typename":"Article"}'

Summary of indexing rules

  • Main content must not define _metadata.fallbackForLocale.
  • Fallback content must define _metadata.fallbackForLocale and be indexed to the fallback locale.
  • _metadata.locale always reflects the actual language of the content.

Query fallback language versions

Fallback handling is automatic. You do not need to modify queries.

Query for the main English version

query MyQuery {
  Article(locale: en) {
    items {
      Title
      Description
    }
  }
}

Response

{
  "Article": [
    {
      "Title": "Germany",
      "Description": "Germany is a country in Europe"
    }
  ]
}

Query for the German version

query MyQuery {
  Article(locale: de) {
    items {
      Title
      Description
    }
  }
}

Response

{
  "Article": [
    {
      "Title": "Deutschland",
      "Description": "Deutschland ist ein Land in Europa"
    }
  ]
}

Query Swedish content with fallback

If Swedish content does not exist, Graph returns the English fallback.

query MyQuery {
  Article(locale: sv) {
    items {
      Title
      Description
    }
  }
}

Response

{
  "Article": [
    {
      "Title": "Germany",
      "Description": "Germany is a country in Europe"
    }
  ]
}

Use fallback languages with SaaS CMS

Configure fallback languages in the CMS to control which language Graph returns when localized content is unavailable.

  1. Open Settings > Languages.
  2. In the Fallback language column, review the current configuration.
  1. Add a new language or edit an existing language to define its fallback language.
  1. Save your changes.

After you update fallback language settings, run a full Optimizely Graph synchronization to apply the changes. When synchronization completes, Graph applies the fallback language rules to all relevant queries.