# {{projectName}} / {{appName}}

Voltro web app scaffold (template: **frontend-i18n**) — a bilingual
(English + German) static site using the **URL-prefix** i18n strategy.

## Boot

```bash
pnpm install
pnpm --filter @{{projectName}}/{{appName}} dev
# → http://localhost:{{port}}
```

## What this shows

- **Typed catalogs** — `src/locales/en.ts` is the source of truth;
  `src/locales/de.ts` uses `defineLocale<typeof en>()`, which fails
  `tsc --noEmit` if a key is missing or extra. Translations can't drift.
- **URL-prefix routing** — the default locale lives at the bare path
  (`/`, `/about`); German is prefixed (`/de`, `/de/about`). Each
  translated page is its own crawlable URL — good for SEO and
  shareable language-specific links.
- **Per-locale SSG** — `src/pages/[locale]/*.tsx` mirror every page and
  enumerate the non-default locales via `getStaticPaths`. `voltro build`
  emits one pre-rendered HTML file per (page × locale):

  ```
  .framework/dist/index.html        ← en (default, bare path)
  .framework/dist/de/index.html     ← de mirror
  .framework/dist/about/index.html  ← en
  .framework/dist/de/about/index.html ← de mirror
  ```

- **Localised `<title>`** — each page's `meta` is a function of
  `{ locale }`, so every variant's `<title>` / `<meta description>` is
  in the right language in the pre-rendered HTML (a plain `meta` object
  would leave the head English on `/de`).
- **Client-side language switch** — the nav's URL-driven
  `<I18nProvider>` (in `src/pages/layout.tsx`) swaps catalogs on
  navigation between `/about` and `/de/about` without a full reload.

## Add a locale

1. Add the code to `SUPPORTED_LOCALES` in `src/lib/locale.ts` AND to
   `locales` in `app.config.ts`.
2. Add `src/locales/<code>.ts` (mirror `en.ts`; the type-check enforces
   parity).
3. Add it to `CATALOGS` in `src/lib/locale.ts`.

The `[locale]` mirrors pick it up automatically — `getStaticPaths`
reads `SUPPORTED_LOCALES`.

## Add a page

Create `src/pages/<name>.tsx` (default locale) **and** a one-line mirror
`src/pages/[locale]/<name>.tsx` that re-exports it (copy
`[locale]/about.tsx`). Without the mirror, only the default-locale URL
is emitted.

See AGENTS.md › *Internationalization (`@voltro/i18n`)* for the full
reference, including the cookie-only strategy product dashboards use.
