Hydrate the mint lists from the live API after paint.
/mints was a snapshot of whatever the API held when `astro build` ran, and stayed that until the next build: a mint indexed at noon was reviewable at once — the 404 resolver saw to that — and simply had no card until 03:30. Every card's rating, review count and status were as stale as the page. The three index pages and the home page's three top-six strips now refetch `GET /api/mints?type=…` once, after paint, and rebuild their grids. The prerendered cards stay: they are the first paint, what a crawler indexes, and the whole page without JavaScript. Hydration only ever replaces them with something newer, and never with nothing — neither a failed fetch nor a well-formed empty array touches a grid that has cards in it. To make that affordable, the list payload grew the facts a chip is drawn from: `nuts`, `capabilities`, and the two probed LNURL fields. /mints and /lnurl-mints were fetching `GET /api/mints/:host` once per mint at build time to read two booleans off each; that N+1 is gone from both, which takes the build from fifty-six requests to one and is what makes the same read possible in a browser. Additive: `MintDetail` already had all four. web/src/lib/mint-cards.ts is MintCard.astro's parallel renderer, the same relationship review-cards.ts has with the reviews panel. Same classes, same data-* attributes — the sort, the search, the rank chips and the shared-element view transitions all read the DOM — and the same i18n, through the page's own inlined catalog rather than a build-time one. Base.astro gained `clientNamespaces`, so the home page can inline the `home.` catalog its strips need to rewrite "All 60 mints →" without putting 2KB of marketing copy on 1,300 mint pages. check-i18n reads the prop off the page, so the two cannot disagree. Verified in Chromium against the built site: 60 prerendered cards become 61 including a mint inserted after the build; sort, search and hide-offline operate on the new cards; /es/mints renders "En línea", "54 reseñas", "4,9" and "Solo fundir"; JavaScript disabled still shows all 60; an aborted or empty API leaves the grid alone; and a navigation away and back re-hydrates. 2016 pages build, link and hreflang checks pass, 30 web tests pass. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
060c7f1a59
commit
14548179a0
+11
-2
@@ -121,13 +121,22 @@ export function missingKeys(): Record<string, string[]> {
|
||||
* key that survives is resolved: a key this locale is missing arrives already filled
|
||||
* with the English string, so the browser needs no fallback catalog and ships exactly
|
||||
* one language.
|
||||
*
|
||||
* `extra` is for a namespace exactly one page's islands need. The home page's grids
|
||||
* hydrate and have to rewrite their own "All 56 mints →" links, which live under
|
||||
* `home.` — a namespace worth about 2KB that every other page, including 1,300 mint
|
||||
* pages, has no use for. Passed per page through `Base.astro`'s `clientNamespaces`
|
||||
* prop, it is inlined where it is read and nowhere else. `check-i18n.mjs` does not know
|
||||
* about this, so a key reached this way must still be in a namespace the checker
|
||||
* accepts, or listed in `CLIENT_NAMESPACES` — see the note there.
|
||||
*/
|
||||
export function clientCatalog(locale: Locale): Catalog {
|
||||
export function clientCatalog(locale: Locale, extra: readonly string[] = []): Catalog {
|
||||
const catalog = catalogFor(locale);
|
||||
const allowed = new Set<string>([...CLIENT_NAMESPACES, ...extra]);
|
||||
const out: Catalog = {};
|
||||
for (const key of Object.keys(BASE_CATALOG)) {
|
||||
const namespace = key.split('.')[0] ?? '';
|
||||
if (!(CLIENT_NAMESPACES as readonly string[]).includes(namespace)) continue;
|
||||
if (!allowed.has(namespace)) continue;
|
||||
out[key] = catalog[key] ?? BASE_CATALOG[key]!;
|
||||
}
|
||||
return out;
|
||||
|
||||
Reference in New Issue
Block a user