Features Apograph CMS on GitHub

Localization plugin

Translating content — and the one setting that decides what happens to a removed language.

Documents 0.5.2 Updated Edit this page Report a problem

On this page

Content locales. A localized content type stores one row per language, tied together by a locale group, and the plugin extends the Content Library so those rows are edited as one record with a language switcher rather than as separate entries.

Install

npm install @apograph/i18n-server @apograph/i18n-admin

Register

// apps/server/src/plugins.ts
import { I18nServerPlugin } from '@apograph/i18n-server';

I18nServerPlugin(config.plugins.i18n);
// apps/admin/src/plugins.ts
import { I18nPlugin } from '@apograph/i18n-admin';

I18nPlugin();

Register the admin half after ContentPlugin() — it fills the Content Library’s locale extensions, so it has to read after the thing it extends.

Configuration

Locales are not environment variables. They are stable product configuration, so they live in apograph.config.ts as literals:

i18n: {
    locales: [
        { slug: 'en', name: 'English', isDefault: true },
        { slug: 'de', name: 'Deutsch' }
    ],
    orphanedLocales: 'fail'
}
SettingWhat it does
localesThe languages content can exist in. Exactly one is the default
orphanedLocalesWhat to do when the database holds rows in a locale no longer listed

Removing a locale hides rows, it does not delete them

Locale slugs are stored on entry rows. Drop de from the array and every German row is intact and unreachable — the worst shape a silent failure can take.

orphanedLocales: 'fail' refuses to boot and puts the choice in front of whoever edited the array. Change it only for a deployment that is knowingly mid-migration.

Shared fields

A field marked shared holds one value across every language. Editing it in the German view changes it in the English one, because there is only one of it. That is the rule that surprises everybody once, and it is worth reading the localization page before modelling a type around it.

The fallback chain

A request for a locale that has no row falls back through a chain ending at the default. Publishing can require a set of locales before an entry may go live — so a record cannot be published half-translated if you do not want it to be.