# Changelog

## [0.2.0] - 2026-08-11

**The domain, not the locale, is the unit of loading.** Measured in
a client app: 573 of 849 msgids were admin-panel copy, and every public
English page downloaded all of them — 30 kB gzipped of a catalog no visitor
can reach.

Breaking:

- Codegen emits `catalog/<locale>/<domain>.ts`, not `catalog/<locale>.ts`.
  Static importers must name the domain.
- `loadCatalog(locale, only?)` takes the domains to load; omitting them loads
  the locale whole, as before.
- `LocaleCatalog` and `Overrides` are `Partial<Record<Domain, DomainCatalog>>`
  and `createT`/`useT` take a `Domain`, not a `string`. A domain typo is now a
  type error; a domain the route tree did not load is not.
- The source locale gets no catalog files. Identity is what msgid passthrough
  already gives, so writing it out only made the source language download its
  own copy. A source locale with real PO files on disk is emitted as before.
- Stale files under `catalog/` are deleted, and reported by `--check`.

Added:

- `I18nProvider` takes a `domains` prop — the chunks that subtree needs. Nest
  a second provider around an admin area to load its domain lazily.
- The extractor understands the domain in the BINDING: every
  `const t = useT("admin")` in a file attributes that file's `t("…")` calls to
  `admin`. Without it, moving a subtree to its own domain kept extracting into
  the default one, and the drift showed up only as untranslated copy at
  runtime. Hook name configurable as `:domain_hook` (default `"useT"`).

## [0.1.1] - 2026-08-11

- `I18nProvider` takes an optional `initialCatalog`, used as the provider's
  initial state. A per-locale server-rendered route tree can now import its
  catalog statically and be translated in the first HTML, instead of shipping
  source language and swapping after hydration. The lazy load is unchanged.

## [0.1.0] - 2026-08-11

Initial extraction from the Vulcora apps (mosis's PO→TypeScript pipeline),
with the production-known defects fixed: nested locale→domain→msgid
catalogs (cross-domain msgid collisions), per-locale output files with lazy
loading (previously one all-locales bundle), a single `%{var}` interpolation
dialect, configurable frontend scanning, and first-class runtime overrides
on both sides (backend override MFA in the `t` macro, `overrides` prop in
the React provider).
