Resident ready Static companion
kari_mikumao Lab

Tooling

Mirai Guide: three languages without a translation CMS

UI catalogs that fail loudly, i18n columns for structure, and reviewed model translation for the catalog.

  • mirai-guide
  • localization
  • i18n

Mirai Guide serves Japanese, English, and Chinese from one deployment.

I split localization into three layers with different correctness guarantees, because interface strings, venue structure, and extracted catalog text all fail in different ways. Treating them the same is how you end up with a blank label at a booth.

Layer 1 - UI Catalogs That Fail Loudly

Interface strings live in per-locale JSON catalogs, bundled eagerly at build time.

Enable a locale without committing its catalog and the build fails, rather than rendering undefined strings at runtime. t() falls back to Japanese key by key. A locale registry decides which bundled languages an operator has revealed to attendees, and the registry can never conjure a language with no catalog behind it.

Two small details carry most of the polish:

  • Templated strings use {name} placeholder interpolation instead of concatenation, so word order stays a per-locale translation decision.
  • Chinese display grouping is explicit. With both variants enabled the picker shows 简 and 繁. A lone zh still reads 简, instead of presenting 中文 with no choice behind it.

Layer 2 - Structure Names as i18n Columns

Venue and structure names are stored as JSON i18n objects ({ ja, en, zh }), validated at the database level, with Japanese as the authoritative source language.

Presentation resolves through the same fallback chain as the UI. A missing translation degrades to Japanese, never to an empty label.

Layer 3 - Reviewed Model Translation for the Catalog

Vendor and product names arrive from Japanese sources at event scale. Far too much for hand translation, far too important for blind machine output.

OpenAI structured outputs produce Japanese, English, and Chinese names and descriptions together with evidence, and those land in the same review queue as everything else. Model output never publishes itself - a human approves each proposal against the source context it was extracted from.

One property holds across all three layers: the failure mode of missing localization is showing correct Japanese. Never a blank, never an unreviewed guess.