Multi-site is a Statamic Pro feature. On a multi-site install the server registers one more tool, entries_localize, and every site needs an access permission, the default site included.
Translate an entry#
An entry belongs to one site. To translate a page, in order:
- Call
entries_localizewith the origin’s id, the target site, and the translated fields indata. - Call
entries_updateon the new entry for further changes. - Call
entries_publishto take it live in that site.
{
"id": "2b931bf4-dab2-467e-894e-c9865273b936",
"site": "de",
"data": { "title": "Erste Fahrt" }
} The new entry is a draft localization. It inherits every field it doesn’t override, data holds its own values, and slug defaults to the origin’s. The response links both sides.
{
"id": "7a1872aa-a2ae-49a3-aca6-93516b443e7a",
"slug": "first-ride",
"site": "de",
"origin_id": "2b931bf4-dab2-467e-894e-c9865273b936",
"status": "draft",
"url": "/de/blog/first-ride",
"result": "saved as draft — not live",
"cp_edit_url": "https://example.com/cp/collections/blog/entries/7a1872aa-a2ae-49a3-aca6-93516b443e7a",
"localizations": {
"en": { "id": "2b931bf4-dab2-467e-894e-c9865273b936", "status": "draft" },
"de": { "id": "7a1872aa-a2ae-49a3-aca6-93516b443e7a", "status": "draft" }
}
} A site that already has the entry is an error naming that entry.
entry '2b931bf4-dab2-467e-894e-c9865273b936' is already in site 'de' as entry '7a1872aa-a2ae-49a3-aca6-93516b443e7a' — change that one with entries_update Mark fields as localizable#
Only fields the blueprint marks localizable can hold a value of their own in a localization. The rest show the origin’s value in every site, and the Control Panel makes them read-only there. blueprints_get reports the flag on each field.
On a localization, data may only name localizable fields, so an agent changes the others on the origin entry. Mark the fields to translate as localizable, and leave the ones that must read the same in every site as they are.
What each collection reports#
statamic_overview gives each collection’s multi-site settings, and can_access on each site.
{
"handle": "blog",
"sites": ["en", "de"],
"propagate": false,
"origin_behavior": "select"
} | Key | Meaning |
|---|---|
sites | The sites the collection is in. |
propagate | When on, entries_create makes a localization in every site at once, and the response lists them under localizations. |
origin_behavior | When root, entries_localize always localizes from the root entry, as in the Control Panel. |
entries_get returns localizations, one key per site of the collection you can access, with the id and status of the entry there, or null where it has none.
The site parameter#
On entries_update and entries_preview, site is a selector and never moves an entry. It must match the entry’s own site, or be omitted. entries_localize is the only way to add an entry to another site.
On a structured collection, a localization joins the target site’s tree under the localization of the origin’s parent, or at the top level when the parent has none there.
Terms and globals#
A term’s localizations are data overrides inside one term, so term ids are the same in every site.
terms_createcreates in the taxonomy’s origin site, its first configured site. Localize afterwards withterms_updateandsite.terms_getwithsiteputs local overrides indata, and what falls back from the origin site ininherited.terms_updatewithslugrenames the term on the origin site, which changes its id and moves the file. On other sites it stores a localized slug override, and it refuses a slug another term has in that site.terms_deleteremoves the term from every site at once.
globals_get and globals_update work per site. With site, the update writes that site’s localization and creates it on first write.
Each site has its own navigation tree. navigations_get and navigations_update take site.
Which tools check site access#
On a multi-site install, every site needs access {site} site, the default site included. Without it, a tool answers with the missing permission.
requires 'access en site' — grant it to a role of [email protected] in the Control Panel This table comes from calling each tool on a real multi-site install, with a role that held every resource permission and no site permission.
| Tools | Needs site access |
|---|---|
All entries_* tools | Yes. entries_localize also needs the target site. |
terms_list, terms_get, terms_create, terms_update | Yes |
globals_get, globals_update | Yes |
navigations_get, navigations_update | Yes |
statamic_overview, blueprints_get | No |
terms_delete | No, because it removes the term from every site at once |
All assets_* tools | No |
All submissions_* tools | No, because submissions aren’t per site |
entries_delete on an origin cascades to all localizations, and it requires site access to each.
Recipes#
Scope an agent to one site. Grant Access {site} site for only that site. Every site is gated, the default site included, so an agent with only Access fr site can’t read or write default-site content. Each denial names the missing permission.
A translation agent. Grant Edit pages entries plus Access {site} site for the source site and each target site. Leave Publish entries off the role to have a person take each translation live, or add it so the agent can call entries_publish itself. Try this one in the permission simulator.