Generated files and migration
What turning locales on generates and the one-time migration.
On this page
With no locales property, nothing about the project changes: no file is generated, rewritten, or wrapped, and the application does not import next-intl. This keeps single-language production builds import-isolated and byte-identical to a project that never configured locales.
Enabling localesLink to this section
Enabling locales is a one-time structural migration handled by the ordinary sync: run pnpm sync and confirm when prompted (non-interactive environments pre-approve it with systhema-core sync --migrate-locales). It touches exactly three things — no glue file is generated:
- wraps
next.config.tswithwithSysthema(nextConfig)(no locale arguments — it readssysthema.config.tsitself; fresh scaffolds already ship this wrapper, so on those projects this step is a no-op); - adds
locales: systhemaConfig.localestopayload.config.ts's plugin options (Payload starters only), so the same opt-in enables Payload content localization without a second locale list; and - converts the owned site shell — Payload starters turn
app/(site)/template.tsxintoapp/(site)/shell.tsx(same content, now receivinglocaleas a prop) and write two managed boundary files atapp/(site)/(systhema)/[[...segments]]/: alayout.tsxthat resolves the route locale and injects it, and anot-found.tsxthat re-exports yourapp/(site)/not-found.tsxso a thrownnotFound()renders the 404 page inside the locale-resolved site shell (styled, localized) instead of as a bare fragment above it. Per-locale pages keep static generation while consumer code stays outside(systhema). No literal[locale]folder is created;src/proxy.tsand the catch-allpage.tsxare not touched at all.
The Next.js starterLink to this section
The known non-Payload Systhema Next starter is the one exception that still uses a literal route boundary: it moves its root layout and page under app/[locale], since arbitrary filesystem routes need that real App Router boundary for distinct static locale URLs — middleware alone cannot make them locale-param-aware. This happens only after opting into locales and needs no extra dependency or hand-edited generated file.
Reversing the migrationLink to this section
Sync keeps a reversible copy under .systhema/locales/ and refuses an unacknowledged shell/route rewrite. If the template or route differs from its known source, sync refuses to convert it even with the flag and prints the manual steps; custom layout and route work is never discarded. Removing locales reverses an untouched conversion byte-for-byte (removes the managed boundary and the pristine shell.tsx, restores template.tsx), but leaves the withSysthema(nextConfig) wrapper and the payload.config.ts locale bridge in place — both are no-ops with locales unset, so there is nothing to unwind there. If the shell was customized, sync refuses reversal until those changes are moved back to template.tsx manually.