Localization

Manage localized content by editing from the content source or extending with Stackbit.

New Feature

This a new feature. Implementation details are subject to rapid change. Please contact us for more information and to stay updated with the latest changes.

Requirements

This feature requires that content sources are managed via Content Source Interface, and is only available in the business and enterprise tiers.

Types of Localization

Stackbit supports two types of localization.

  • Object-level localization: Each document or object is associated with a single locale.
  • Field-level localization: A document or object may have multiple locales, as determined by the fields within that object.

Object vs Field Example

For example, consider a site that has a Post model with title and body fields, and serves content in both the fr (French) and de (German) locales.

If using object-level localization, there would be two documents of type Post, one for fr and another for de.

If using field-level localization, there would only be a single object, while title might be an object with properties fr and de, storing the string reference to the value in each locale.

Configuring Localization

Models or their fields need to set the localized property to true in the schema, and the content objects themselves to have a locale property assigned, where the value is the string reference to that field (e.g. de for German language content).

Overriding CSI Modules

In some cases, locale behavior may be provided by the CSI module. If not, the CSI module can be extended to provide the appropriate logic to its internal methods, and to apply the appropriate properties to the models and documents.

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
export default {
  contentSources: [
    new ContentfulContentSource({
      spaceId: process.env.CONTENTFUL_SPACE_ID,
      environment: process.env.CONTENTFUL_ENVIRONMENT,
      previewToken: process.env.CONTENTFUL_PREVIEW_TOKEN,
      accessToken: process.env.CONTENTFUL_MANAGEMENT_TOKEN,
    }),
  ],
  // Add `localized` property to localized models.
  mapModels({ models }) {
    return models.map((model) => {
      // `LOCALIZED_MODELS` is an array of model name strings.
      if (LOCALIZED_MODELS.includes(model.name)) {
        return { ...model, localized: true }
      }
      return model
    })
  },
  // Add `localized` field values to localized objects.
  mapDocuments({ documents }) {
    return documents.map((document) => {
      // `LOCALIZED_MODELS` is an array of model name strings.
      if (LOCALIZED_MODELS.includes(document.modelName)) {
        // `getDocumentLocale` returns the appropriate locale string for the document.
        const locale = getDocumentLocale(document)
        return { ...document, locale }
      }
      return document
    })
  },
  // Alternatively, use `models` to extend models in a more static way.
  models: {
    // ...
  },
}

Here's a more complete example using Contentful as the content source.

Access Control

Access to one or more locales can be controlled through your project settings.

When adding a member or a team to the project, they can be limited to a single locale or be given access to all locales (global). If nothing is selected in the restriction dropdown, the user will have full access to all locales (global).

Locale Access Control
Locale Access Control

See below for more information on locale modes (global vs specific).

Locale Modes

There are 2 modes for the locale switcher:

  • Global: Users can view, create, edit and publish objects of all locales.
  • Specific: Users can view, create, edit, and publish only objects within the selected locale. They can also view all objects that are not localized, but can only edit localized fields within those objects.

These modes are used to handle access control, along with the current editing context. The next section covers governance on field-level localization. More on editing below.

Governance for Field Localization

While you can control editing within a specific locale, full governance and publishing control is not available for field-level localization.

Localization Method
Governance
Publishing
Object-Level
✔️
✔️
Field-Level

This is because editors will have access to view non-localized content. And there is no way to be able to publish only values within a specific locale for a specific field. More on both editing and publishing below.

Editing Localized Content

Managing localized content is done within the context of the current locale mode. This is controlled through the locale switcher, and it affects how objects are viewed, created, edited, published, and stored as presets.

Locale Switcher

The current locale can be set via the locale switcher, found in the top bar controls within the visual editor.

Localization - Choose Locale
Localization - Choose Locale

Making a selection here changes the editing context for all content in the site.

Default Locale

There is always a defaultLocale (most commonly en-US, but it can be changed). The default locale is the one immediately below Global in the locale switcher dropdown.

Creating New Objects

When a specific locale is selected, objects will be created with that locale. It is not possible to create objects in more than one locale or in a different locale other than the current (set via the local switcher).

When Global mode is selected, the user has the ability to create multiple locales at once by selecting checkboxes.

New Object with Locales
New Object with Locales

This behavior of this process depends on whether the object is localized or has localized fields:

  • Object-Level: There will be multiple tabs. The editor must fill out the required fields in each of the selected locales before being able to create the object. This results in multiple objects, one per selected locale.
  • Field-Specific: When selecting multiple locales, the editor must fill out values for the default locale (required to build the object's base fields), along with field that are both required and localized in other tabs. This action creates only one object, while additional selected locales will be added as additional values to the existing object.

Editing Existing Objects

Locale flags will show up next to objects and fields that are localized.

Localized Fields
Localized Fields

In Global mode, all objects are shown and editable. In a specific locale, only objects of the selected locale can be edited, though objects without a locale will still be shown.

Users with access to the Global locale will be able to edit:

  • All objects are editable, including non localized objects
  • Localized fields, within their default locale

Users with access to a specific locale are able to edit:

  • Objects of accessible locales (all others will be disabled)
  • Localized fields within only the selected locale (fields without a locale are disabled, but can be clicked to drill down to child objects)

Localized Presets

When in a specific locale, presets will be saved and visible only in the current locale as well as Global mode.

When in Global mode, new presets will be visible to all other locales and can be used by all locales.

Publishing Localized Content

In a specific locale, the publish dropdown will only show objects that are localized to the currently-selected locale, along with objects that have localized fields. Publishing can not be focused on a specific localized field value.

Users with access to the Global view will have visibility of changes and be able to publish all content.

Custom Visual Editing Behavior

You can customize how your website preview responds to localization changes in the visual editor using client-side JavaScript.

setLocale

Enables you to change the current locale, which will update the locale switcher.

  • 1
window.stackbit.setLocale(locale)

See the reference for details.

stackbitLocaleChanged

Listen for an editor to interact with the locale switcher and change the current locale.

  • 1
  • 2
  • 3
  • 4
window.addEventListener('stackbitLocaleChanged', (event) => {
  const locale = event.detail.locale
  // Add custom behavior ...
})

This may be useful for redirecting the current page to a version with the newly-selected locale. See the reference for details.