Localizing a static site into 6 languages at build time with an LLM — and validating every string A developer built a build-time localization pipeline for the LiveToka static site that uses an LLM to translate English source strings into Japanese, Korean, Vietnamese, Portuguese, and Chinese, generating per-language pages without adopting an i18n framework. The pipeline extracts HTML text and JavaScript t() keys into per-language dictionaries, sends only missing keys to the model in batches of about 40 with IDs, and validates every returned string for placeholders, HTML tags, leading emoji, and brand names before accepting it. The build refuses to emit a localized page if any key is missing, and an identity-dictionary diff test confirmed the HTML walker left the original file intact apart from ampersand normalization. LiveToka https://livetoka.com started as one English page — a hand-written index.html that is the app — plus a few vanilla JS files. No framework, no i18n library. I wanted real localized pages for Japanese, Korean, Vietnamese, Portuguese and Chinese speakers: menus, buttons, error messages, dialogs, FAQ, everything. Rewriting the site around an i18n framework wasn't worth it. Instead I built a small pipeline that keeps English as the single source of truth and generates /ja/ , /ko/ , /vi/ , /pt/ , /zh/ and /zh-tw/ at build time. Here's how it works and what bit me. public/index.html English master public/ .js with t '…' │ extract strings │ extract t '…' keys └──────────────► dictionary/