@urbicon-ui/i18n 8.20.0 → 8.22.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/README.md +18 -11
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -14,7 +14,7 @@ The locale lives in **context**, not a module-global singleton — so concurrent
14
14
  bun add @urbicon-ui/i18n
15
15
  ```
16
16
 
17
- Peer dependencies: `svelte` (^5.40 — uses runes + `createContext`-era context). No SvelteKit needed: the package imports neither `$app/*` nor `@sveltejs/kit`, so it works in any Svelte 5 project — the request-scoped locale below is what keeps it SSR-correct wherever you render.
17
+ Peer dependencies: `svelte` (^5.57.0 — uses runes + `createContext`-era context). No SvelteKit needed: the package imports neither `$app/*` nor `@sveltejs/kit`, so it works in any Svelte 5 project — the request-scoped locale below is what keeps it SSR-correct wherever you render.
18
18
 
19
19
  ## Quick Start
20
20
 
@@ -33,6 +33,7 @@ Peer dependencies: `svelte` (^5.40 — uses runes + `createContext`-era context)
33
33
  ```
34
34
 
35
35
  <!-- typecheck -->
36
+
36
37
  ```ts
37
38
  // +layout.server.ts — resolve the locale per request (SSR), cookie + Accept-Language
38
39
  import { resolveLocale } from '@urbicon-ui/i18n';
@@ -110,9 +111,13 @@ import en from '../translations/en';
110
111
 
111
112
  // en is the eager base; de is a lazy dynamic-import loader (see "Locale
112
113
  // code-splitting" below), so English-only apps never bundle the de catalog.
113
- export const blocksI18n = createPackageI18n('blocks', { en }, {
114
- loaders: { de: () => import('../translations/de').then((m) => m.default) }
115
- });
114
+ export const blocksI18n = createPackageI18n(
115
+ 'blocks',
116
+ { en },
117
+ {
118
+ loaders: { de: () => import('../translations/de').then((m) => m.default) }
119
+ }
120
+ );
116
121
 
117
122
  // The context-scoped hook (re-exported for components)
118
123
  export const useBlocksI18n = blocksI18n.useTranslate;
@@ -193,7 +198,7 @@ resolveLocale(request, {
193
198
 
194
199
  ## Formatting with `Intl` — `resolveDateLocale`
195
200
 
196
- Building your own date or number component? Never hand `Intl` an `undefined` locale: it follows the *runtime*, which is your server process during SSR and the user's browser after hydration, so the same value renders two ways across the boundary. `resolveDateLocale` is the chain the library's own components use:
201
+ Building your own date or number component? Never hand `Intl` an `undefined` locale: it follows the _runtime_, which is your server process during SSR and the user's browser after hydration, so the same value renders two ways across the boundary. `resolveDateLocale` is the chain the library's own components use:
197
202
 
198
203
  ```ts
199
204
  import { resolveDateLocale, useI18n } from '@urbicon-ui/i18n';
@@ -231,11 +236,12 @@ Vite/Rollup splits each dynamic import into its own chunk, so only the active lo
231
236
 
232
237
  ### SSR: eager-register the lazy locale for non-base apps
233
238
 
234
- The provider's on-mount load runs in a **client-only** `$effect`. So under SSR a lazy non-base initial locale (e.g. a German app) renders the *fallback* (English) on the server and the first client paint, then flips to German once the chunk lands — a text flash and a possible hydration text mismatch. That is not acceptable as the default for a server-rendered app in that locale.
239
+ The provider's on-mount load runs in a **client-only** `$effect`. So under SSR a lazy non-base initial locale (e.g. a German app) renders the _fallback_ (English) on the server and the first client paint, then flips to German once the chunk lands — a text flash and a possible hydration text mismatch. That is not acceptable as the default for a server-rendered app in that locale.
235
240
 
236
241
  The fix is to register the bundle **eagerly, once at server/app start**. The registry is module-global and holds only static, request-identical translation data, so a single startup registration is SSR-safe (it carries no per-request state). Every package factory returns `registerLocale(locale, bundle)` for this; `@urbicon-ui/blocks` re-exports it as `registerBlocksLocale`:
237
242
 
238
243
  <!-- typecheck -->
244
+
239
245
  ```ts
240
246
  // src/hooks.server.ts (or any module evaluated once at server start)
241
247
  import { registerBlocksLocale } from '@urbicon-ui/blocks';
@@ -294,6 +300,7 @@ it('en/de key parity', () => {
294
300
  ## API Surface
295
301
 
296
302
  <!-- typecheck -->
303
+
297
304
  ```ts
298
305
  // Provider + hooks + server helper
299
306
  import {
@@ -376,7 +383,7 @@ urbicon i18n audit src/ --translations src/lib/translations # parity + unused +
376
383
  urbicon i18n unused --dynamic-keys 'errors.*' --json # just the scan, allowlisting dynamic key families
377
384
  ```
378
385
 
379
- It gates (exit 1) on parity errors + used-but-undefined; unused keys and hardcoded strings are advisory (`--strict` gates them too). The pure scanner core — `scanSources`, `findUnusedKeys`, `findHardcodedStrings` — is on the `@urbicon-ui/i18n/audit` subpath for programmatic use, with `typescript` + `svelte` as optional peers it lazily imports. See the [CI gate template](../design/templates/ci-github.yml).
386
+ It gates (exit 1) on parity errors + used-but-undefined; unused keys and hardcoded strings are advisory (`--strict` gates them too). The pure scanner core — `scanSources`, `findUnusedKeys`, `findHardcodedStrings` — is on the `@urbicon-ui/i18n/audit` subpath for programmatic use, with `typescript` + `svelte` as optional peers it lazily imports. See the [CI gate template](https://github.com/urbicon/ui/blob/main/packages/design/templates/ci-github.yml).
380
387
 
381
388
  ## Development
382
389
 
@@ -388,10 +395,10 @@ bun --filter='@urbicon-ui/i18n' run test:run # vitest
388
395
 
389
396
  ## Related
390
397
 
391
- - [`@urbicon-ui/blocks`](../blocks/) — consumes this package; exports `useBlocksI18n`, `<LocaleSwitcher>`
392
- - [`@urbicon-ui/table`](../table/) — ships its own namespace (`table.*`), exports `useTableI18n`
393
- - [`@urbicon-ui/auth`](../auth/) — ships EN/DE bundles; exports `useAuthLocale`
394
- - [Architecture Overview](../../docs/ARCHITECTURE.md#i18n)
398
+ - [`@urbicon-ui/blocks`](https://github.com/urbicon/ui/blob/main/packages/blocks/README.md) — consumes this package; exports `useBlocksI18n`, `<LocaleSwitcher>`
399
+ - [`@urbicon-ui/table`](https://github.com/urbicon/ui/blob/main/packages/table/README.md) — ships its own namespace (`table.*`), exports `useTableI18n`
400
+ - [`@urbicon-ui/auth`](https://github.com/urbicon/ui/blob/main/packages/auth/README.md) — ships EN/DE bundles; exports `useAuthLocale`
401
+ - [Architecture Overview](https://github.com/urbicon/ui/blob/main/docs/ARCHITECTURE.md#i18n)
395
402
 
396
403
  ```
397
404
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@urbicon-ui/i18n",
3
- "version": "8.20.0",
3
+ "version": "8.22.0",
4
4
  "description": "Runes-based localization for Svelte 5 apps and the Urbicon UI design system",
5
5
  "license": "MIT",
6
6
  "repository": {