Docs

This page isn't translated yet

next

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:

  1. wraps next.config.ts with withSysthema(nextConfig) (no locale arguments — it reads systhema.config.ts itself; fresh scaffolds already ship this wrapper, so on those projects this step is a no-op);
  2. adds locales: systhemaConfig.locales to payload.config.ts's plugin options (Payload starters only), so the same opt-in enables Payload content localization without a second locale list; and
  3. converts the owned site shell — Payload starters turn app/(site)/template.tsx into app/(site)/shell.tsx (same content, now receiving locale as a prop) and write two managed boundary files at app/(site)/(systhema)/[[...segments]]/: a layout.tsx that resolves the route locale and injects it, and a not-found.tsx that re-exports your app/(site)/not-found.tsx so a thrown notFound() 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.ts and the catch-all page.tsx are 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.