Localization
Read content in multiple languages — request a specific locale via the Public API and understand the fallback behaviour.
Localization
Atlas is multi-locale by design. A single entry (or page) can hold values for several languages at once: one base value for the default locale plus any number of per-locale translations. The Public API returns the right values for the language you request, falling back to the base when a translation is missing.
How it fits together
| Concept | Where it lives | Purpose |
|---|---|---|
| Workspace locales | Dashboard → Settings → Locales | The set of languages a workspace supports, with one marked as default. |
| Localizable field | Content type field (localizable: true) | Marks which fields can carry per-locale values. |
data | Entry payload | Field values for the default locale — all fields appear here. |
translations | Entry payload | Per-locale overrides — only localizable fields, keyed by locale code. |
Locale codes are short language tags such as en, id, or fr (2–10 characters).
Setting up locales and translations
Configuring workspace locales, marking fields as localizable, and providing translated values are all done through the Atlas dashboard or via the Admin API (documented in a later phase).
Reading a specific locale
Request a language by adding ?locale= to any Public API list or detail endpoint.
curl "https://api.atlas.latellu.com/api/v1/public/entries/getting-started-with-headless-cms?locale=id" \
-H "X-API-Key: atlas_live_abc123xyz"?locale= is available on both entry endpoints:
| Endpoint | Description |
|---|---|
GET /public/entries?type={slug}&locale={code} | List published entries of a content type in a locale. |
GET /public/entries/{entrySlug}?locale={code} | Fetch a single published entry in a locale. |
Understanding the response
The entry's data object always contains default-locale values for every field.
The translations.<locale>.data object contains values that override data for
localizable fields only. Your frontend should merge these: use the translation value
when present, otherwise fall back to data.
{
"success": true,
"data": {
"slug": "getting-started-with-headless-cms",
"status": "published",
"data": {
"title": "Getting Started with Headless CMS",
"summary": "A beginner-friendly introduction to decoupled content management.",
"cover_image": {
"url": "https://cdn.atlas.latellu.com/blog/covers/headless-cms-intro.webp",
"width": 1200,
"height": 630
},
"published_at": "2026-05-10T08:00:00Z"
},
"translations": {
"id": {
"data": {
"title": "Memulai dengan Headless CMS",
"summary": "Pengenalan ramah pemula untuk manajemen konten terpisah."
}
}
}
}
}In this example cover_image and published_at are not localizable — they have no
per-locale override, so you always read them from the top-level data. title and
summary are localizable and appear in translations.id.data for Indonesian.
Fallback behaviour
If you request a locale that the entry has no translation for, Atlas returns the
default-locale values rather than an empty result. The single-entry endpoint flags
this with is_fallback: true, so your frontend can show a "translation unavailable"
hint when needed.
{
"success": true,
"data": {
"slug": "getting-started-with-headless-cms",
"status": "published",
"is_fallback": true,
"data": {
"title": "Getting Started with Headless CMS",
"summary": "A beginner-friendly introduction to decoupled content management."
},
"translations": {}
}
}Pages are localizable too
Pages support the same model: SEO metadata and individual content blocks can each
carry per-locale translations. Each block's data/translations shape comes from
its block type (a content type with is_block: true) — use the
Schema Explorer to look up a block type's
fields the same way you would for an entry.
Next Steps
- Entries — the full entry structure and
data/translationsshape. - Pagination & Filtering — combine
localewith paging and filters.