Localize an entry
Locales are org-scoped. Every entry stores its locale as a string column; if the locale is omitted on create, the org's default locale is used. There is no automatic translation — each locale is its own entry row, written by hand or imported.
TL;DR
cms_list_locales— see what's configured.cms_create_localefor each missing language. The first locale added auto-becomes default.- Create a base entry:
cms_create_entrywith the default locale. - Fan out: one
cms_create_entryper additional locale, with the sameslug. - Publish each per-locale entry independently.
Step 1 — verify locales
{ "name": "cms_list_locales", "arguments": {} }
Returns [{ code, name, isDefault }, ...]. Codes are ISO 639-1 (en, nb) or BCP-47 (en-GB, nb-NO).
Step 2 — add missing locales
{
"name": "cms_create_locale",
"arguments": { "code": "nb", "name": "Norsk bokmål", "isDefault": false }
}
If isDefault: true, the call atomically clears isDefault on every other locale for this org. The very first locale you create is implicitly the default regardless of the flag.
Step 3 — author the base entry
Pick the default locale (or whichever you treat as canonical). Create the entry once:
{
"name": "cms_create_entry",
"arguments": {
"collection": "blog",
"slug": "spring-launch-2026",
"locale": "en",
"data": { "title": "Spring Launch 2026", "body": "..." },
"status": "draft"
}
}
Step 4 — fan out per locale
For each additional locale, create a separate entry with the same slug and the new locale. Slug uniqueness in CMS is (collection, slug, locale), so this is allowed.
{
"name": "cms_create_entry",
"arguments": {
"collection": "blog",
"slug": "spring-launch-2026",
"locale": "nb",
"data": { "title": "Vårlansering 2026", "body": "..." },
"status": "draft"
}
}
Repeat for each locale. Translations live in data — the field schema is per-collection, so make sure every locale supplies the required fields.
Step 5 — publish per locale
Use skill://cms/publish-entry for each entry. There is no atomic "publish all locales" tool — publish each one individually. If the order matters (e.g. you don't want the English version live while the Norwegian one is still missing), publish the secondary locales first and the canonical one last.
Switching the org's default locale
{ "name": "cms_set_default_locale", "arguments": { "code": "nb" } }
This atomically clears isDefault on every locale for the org and sets it on the target. The cascade is two-statement, but executes in a single transaction.
Effect on entries:
- Existing entries keep their
localefield — nothing rewrites them. - New entries created without an explicit
localewill now inheritnbinstead of the previous default. - Public delivery API: locale fallback (per request) follows the new default if the requested locale is missing.
What NOT to do
- Don't try to "translate in place" by changing an entry's
localefield. That orphans the slug-pair you started with and silently breaks any inbound link. Create a sibling entry instead. - Don't depend on entries from a deleted locale. There's no built-in cleanup; entries with a
localethat no longer exists incms_list_localesare still in the table but won't be served by the locale-aware delivery API. - Don't switch the default locale during a release window. New entries authored after the switch will land in the new default; if a publishing job partly ran under the old default and finished under the new one, you'll have a confusing mix.
Related
skill://cms/publish-entry— publishing each per-locale entry.skill://cms/migrate-content— bulk copying entries between locales.