Wire locale catalogs, repair mint terminology, and confirm login with a toast.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -375,8 +375,31 @@ Both gate a deploy. See [Languages](#languages) for what they look for.
|
||||
|
||||
## Languages
|
||||
|
||||
English, Spanish and Dutch. English is the site as it was; the other two are the same
|
||||
site, prerendered again.
|
||||
Twenty-four, listed in `web/src/i18n/config.ts`. English is the site as it was; the other
|
||||
twenty-three are the same site, prerendered again, 84 pages each.
|
||||
|
||||
English, Spanish and Dutch are hand-written. The other twenty-one began as bulk machine
|
||||
translation, and they are in two states.
|
||||
|
||||
**German, Danish, Swedish, Indonesian, Vietnamese and Turkish** have had a full
|
||||
terminology pass: every string that names a mint, and every label, title and meta
|
||||
description on the home page, the mint list and a mint page. The machine had translated
|
||||
the site's central noun into the local word for a coin factory (`Münzprägeanstalt`,
|
||||
`mincovna`, `darphane`) or, in the Germanic languages, into the *sweet*: Danish and
|
||||
Swedish shipped `Cashu-pastiller`, "Cashu lozenges", and Swedish offered to sort your
|
||||
`minttabletter`. Indonesian had `permen`, Vietnamese `cây mint`, the mint plant. Those
|
||||
six now say `mint`, and `sats`, `ecash` and `Lightning` survive untranslated in them as
|
||||
the glossary requires.
|
||||
|
||||
**The other fifteen** still carry that damage in their body copy, in the same shapes:
|
||||
Czech `mincovny`, Polish `mennice`, Romanian `monetării`, Greek `νομισματοκοπείο`. Their
|
||||
chrome, titles and meta descriptions are repaired, so what a reader meets first is right,
|
||||
but the prose underneath is not. Roughly 400 strings, concentrated in the four inflected
|
||||
languages where a word-level fix needs case-correct edits inside running sentences, which
|
||||
is a native speaker's job rather than a careful search and replace.
|
||||
|
||||
`web/src/i18n/GLOSSARY.md` is where a pass starts, and the house rules at the top of it
|
||||
hold in every language, particularly the first row of the table.
|
||||
|
||||
### Routing
|
||||
|
||||
@@ -404,9 +427,9 @@ opened the English page is not overruled by a browser setting they configured ye
|
||||
The language control in the header is how you change language, and it lands on the page
|
||||
you were already reading.
|
||||
|
||||
One file per route emits all three: pages live under `web/src/pages/[...locale]/`, and
|
||||
One file per route emits every locale: pages live under `web/src/pages/[...locale]/`, and
|
||||
`localePaths()` in `web/src/i18n/paths.ts` is their `getStaticPaths`. There is one copy
|
||||
of each page's markup, translated by `t()`, rather than three copies to keep in step.
|
||||
of each page's markup, translated by `t()`, rather than twenty-four to keep in step.
|
||||
|
||||
### What is and is not translated
|
||||
|
||||
@@ -425,9 +448,10 @@ Never translated, because it is data rather than copy:
|
||||
A mint's own `description` is the first sentence of its page's meta description, verbatim.
|
||||
Only when a mint has published none does the site write that sentence itself.
|
||||
|
||||
### Adding a fourth language
|
||||
### Adding a language
|
||||
|
||||
Four steps, and the build tells you if you miss one.
|
||||
Five steps. Four of them the build tells you about; the fifth it cannot, which is why it
|
||||
has a test of its own.
|
||||
|
||||
1. **`web/src/i18n/GLOSSARY.md`** — add the column and decide the terms first. This is
|
||||
the step people skip, and it is the one that costs later: a reader who meets two words
|
||||
@@ -453,6 +477,15 @@ Four steps, and the build tells you if you miss one.
|
||||
TypeScript exists. `check-i18n` compares the two lists and fails if they disagree, so
|
||||
forgetting this is a build error rather than a mystery.
|
||||
|
||||
5. **`web/src/i18n/index.ts`** — `import pt from './pt.json'` and add `pt: pt as Catalog`
|
||||
to `CATALOGS`. This is the step to get right, because it is the only one nothing
|
||||
downstream complains about: `catalogFor()` falls back to English by design, so a
|
||||
locale listed in `LOCALES` with no catalog behind it does not fail the build. It
|
||||
prerenders the whole English site under the new `lang`, the new URL prefix and a full
|
||||
reciprocal hreflang set, and tells every crawler those pages are a different language.
|
||||
Twenty-one locales shipped in exactly that state once. `pnpm test` now fails on it:
|
||||
see `web/test/i18n-wiring.test.mjs`.
|
||||
|
||||
That is the whole change. The Astro i18n config, the routes, the switcher, the hreflang
|
||||
sets, the `og:locale:alternate` list and the sitemap all read from `LOCALES` and pick the
|
||||
new language up on the next build.
|
||||
@@ -505,7 +538,7 @@ English. Islands read it through `useI18n()` in `web/src/i18n/client.ts`.
|
||||
The alternative, importing `es.json` from an island, does not work here: island chunks
|
||||
are shared across every locale, so anything imported into one is downloaded by all of
|
||||
them. A dynamic `import()` keyed on locale would avoid that but costs a round trip on the
|
||||
critical path of every island and leaves all three catalogs sitting in `dist/_astro/`.
|
||||
critical path of every island and leaves every catalog sitting in `dist/_astro/`.
|
||||
Inlining travels in HTML the page was sending anyway.
|
||||
|
||||
It is in the body rather than the head because the view transition router replaces the
|
||||
@@ -658,10 +691,11 @@ below rather than by a test for Cashu.
|
||||
reviews panel work unchanged), a route in `targetPath` (`web/src/lib/feed-resolve.ts`),
|
||||
nav entries in `Topbar.astro` and `Footer.astro`, and sitemap entries in
|
||||
`src/pages/sitemap.xml.ts`.
|
||||
5. **Copy.** A namespace in `en.json`, `es.json` and `nl.json`, the namespace added to
|
||||
5. **Copy.** A namespace in `en.json` and in every other catalog, the namespace added to
|
||||
`CLIENT_NAMESPACES` if an island renders any of it, and a row in
|
||||
`web/src/i18n/GLOSSARY.md` for every term the ecosystem introduces. `pnpm check:i18n`
|
||||
fails the build until all three catalogs have the keys.
|
||||
warns per locale until every catalog has the keys; until then they fall back to
|
||||
English.
|
||||
|
||||
Not in scope, deliberately: **LNURL**. Nothing in the routes, event kinds, schema values
|
||||
or copy refers to it, and it is planned as a later stage rather than half-built now.
|
||||
|
||||
Reference in New Issue
Block a user