Localization
Manage localized content by editing from the content source or extending with Visual Editor.
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
Visual Editor 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.
How Visual Editor handles localization for you project depends on a number of factors, including the content source(s) being used, the site's localization strategy, along with the provided Visual Editor configuration.
# Configure 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).
# Override 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.
// stackbit.config.js
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: {
// ...
}
};
Tip
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 visual editor 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).
See below for more information on locale modes (global vs specific).
# Locale modes
There are 2 modes for the locale switcher: global and locale. These modes are used to handle access control, along with the current editing context.
When in global mode:
- Object-level: Users can view, create, and publish objects of all locales.
- Field-specific: Objects are common across locales. Users can view, create, and publish all objects, with the ability to set field values in any locale.
When in locale mode:
- Object-level: Users can view, create, edit, and publish only content entries within the selected locale. Non-localized objects can be viewed but not edited from a specific locale.
- Field-specific: Users can view, create, edit, and publish only fields of the content entry within the selected locale. Non-localized objects can be viewed but not edited from a specific locale.
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.
# Edit 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 Visual Editor.
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.
# Create new objects
Creating objects in Visual Editor differs depending on the chosen localization strategy:
When using object-level localization in global mode, 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.
When using object-level localization in locale mode, it is only possible to create a new object in that locale (set via the locale switcher).
When using field-specific localization, the editor must fill out values for the default locale (required to build the object's base fields), along with fields that are 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. To avoid editors accidentally generating content in multiple locales, creating objects with field-specific localization is only possible within global mode.
# Edit existing objects
The editing experience differs depending on the localization strategy being used.
- Object-level: In global mode, all objects are shown and editable. In locale mode, only objects of the selected locale can be edited, though objects without a locale will still be shown.
- Field-specific: Locale flags will show up next to objects and fields that are localized. In global mode, only fields of the default language are accessible. In locale mode, the fields of the selected locale will be shown.
# Localized presets
Localized presets work differently depending on the localization strategy and mode being used:
In both object-level and field-specific, 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.
In the case of field-specific localization, the same (and unique) preset values will be used in any locale. Presets cannot store different values for different locales. Instead, save multiple templates, one for each desired locale.
# Publish 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 Visual Editor using client-side JavaScript.
# setLocale
Enables you to change the current locale, which will update the locale switcher.
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.
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.
Did you find this doc useful?
Your feedback helps us improve our docs.