---
title: "Generated files and migration"
description: "What turning locales on generates and the one-time migration."
requested_language: fr
language: en
translation_notice: "This page isn't translated yet"
url: https://docs.systhema.app/fr/next/nextjs/locales/generated-files
version: unreleased (main)
docs_index: https://docs.systhema.app/fr/next/llms.txt
---
> This page isn't translated yet. Showing English.


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 locales

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 starter

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 migration

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.

## Related

- [Frontend locales](https://docs.systhema.app/fr/next/nextjs/locales.md)
- [Localizing an existing site](https://docs.systhema.app/fr/next/payload/localization/migrating-existing-site.md)
- [systhema-core](https://docs.systhema.app/fr/next/cli/systhema-core.md)
