From 17acf5ec80a0c0b0acc44a6a8373e154c68d4748 Mon Sep 17 00:00:00 2001 From: Adam Soltys Date: Wed, 24 Jun 2026 08:59:31 -0700 Subject: Split translations into per-language files, lazy-loaded Only English is bundled in index.html now; the other 19 languages are emitted as dist/locales/.json and fetched on demand when a visitor actually uses one (via auto-detect, the picker, or ?lang=xx). This drops index.html from ~511KB to ~318KB; a non-English visitor fetches just their one ~8-10KB locale, which the service worker then caches for offline use. t() falls back to English until a locale resolves. - i18n.js keeps only en + a loadLocale() fetcher; locale data moved to src/locales/*.json. - build.js emits dist/locales/; dev.js serves /locales/.json. - Deploy hook publishes the locales/ subdir. Co-Authored-By: Claude Opus 4.8 (1M context) --- dev.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'dev.js') diff --git a/dev.js b/dev.js index dde8813..b1d64d8 100644 --- a/dev.js +++ b/dev.js @@ -9,11 +9,19 @@ Bun.serve({ port, async fetch(req) { try { - if (new URL(req.url).pathname === '/jsqr.js') { + const path = new URL(req.url).pathname; + if (path === '/jsqr.js') { return new Response(await buildJsQr({ minify: false }), { headers: { 'content-type': 'text/javascript; charset=utf-8' }, }); } + const loc = path.match(/^\/locales\/([a-z]{2})\.json$/); + if (loc) { + const f = Bun.file('src/locales/' + loc[1] + '.json'); + return (await f.exists()) + ? new Response(f, { headers: { 'content-type': 'application/json; charset=utf-8' } }) + : new Response('{}', { status: 404, headers: { 'content-type': 'application/json' } }); + } const html = await buildHtml({ minify: false }); return new Response(html, { headers: { 'content-type': 'text/html; charset=utf-8' }, -- cgit v1.2.3