
Dodání třiceti jazyků bez záchranné sítě
GeekBye v1.8.3 zapojil react-i18next a přeložil celou aplikaci do 30 jazyků. Část s knihovnou byla rutina. Zajímavá část je to, co chybělo: žádná kontrola parity klíčů a žádný extraktor stringů — takže hardcoded angličtina se protáhla, dánský překlep se dostal do produkce a changelog se nedokázal shodnout, jestli aplikace mluví 28, 29 nebo 30 jazyky.
Některá vydání jsou funkce. GeekBye v1.8.3 jednou vypadá — „aplikace teď mluví 30 jazyky" —, ale ta funkce byla ta snadná část a není to, o čem je tento text. Mezi 17. a 19. únorem 2026 dva pull requesty zapojily react-i18next do aplikace, refaktorovaly každý hardcoded anglický string do volání překladu a zabalily třicet locale souborů. To je skutečná práce, ale je to ten druh práce, který je knihovna navržena udělat rutinním. Zajímavé inženýrství je všechno, co vydání nepostavilo — záchranná síť, která by chytila to, co dodalo rozbité.
Zapojení bylo těch snadných 80 %
Infrastrukturní commit přidal react-i18next nad i18next a udělal konvenční věc: i18n/index.ts, který volá initReactI18next, staticky importuje všech třicet locale JSONů a registruje je pod jedním objektem resources. Žádné lazy loading — každý jazyk cestuje v bundlu. Překladové stringy žijí v src/i18n/locales/*.json jako ploché mapy s namespacem přes tečku: sidebar.meetings, startMeeting.start, jeden klíč k jednomu stringu.
Migrace z hardcoded angličtiny na t('key') proběhla poctivým způsobem, skupina komponent po skupině komponent, a to zametání si můžeš přečíst v commit logu: nejdřív sidebar, navigace a chat; pak nastavení, login a onboarding; pak meetings, dashboard, toasty a tooltipy navbaru. Každý commit nahradil dávku literálních stringů voláními překladu. Dvacet devět neanglických souborů přistálo v jediném commitu — pád devíti tisíc řádků, který přeložil anglický zdroj do všeho od bulharštiny po vietnamštinu.
Nic z toho není těžké udělat správně, protože udělat to špatně je hlasité: chybějící provider spadne, špatně formátovaný JSON se nenaparsuje, špatný import rozbije build. Knihovna ti dává zábradlí pro mechanické chyby. Co ti nedává, je zábradlí pro chybu, která se skutečně stala.
Tři nastavení jazyka a proč je to správně
Než se dostaneme k tomu, co se rozbilo, jednu věc v1.8.3 trefil přesně, protože je to rozlišení, které spousta aplikací splošťuje, a neměla by. Po tomto vydání má GeekBye tři nezávislá nastavení jazyka:
- Jazyk AI odpovědí (
output_language) — v čem asistent odpovídá. Nejstarší ze tří, z listopadu 2025. - Jazyk transkripce (
transcriptLanguage) — do čeho speech engine přepisuje tvůj mikrofon. Zaveden o pár vydání dřív, ve v1.7.6. - Jazyk aplikace (
app_language) — jazyk tlačítek, menu a onboardingu. Nový ve v1.8.3.
To jsou opravdu různé osy. Vývojář v Berlíně může chtít německé rozhraní, anglické AI odpovědi (protože to je jazyk dokumentace, kterou vkládá) a anglickou transkripci (protože schůzka je v angličtině). Sloučit to do jednoho nastavení „jazyka" by bylo pro toho člověka špatně, a onboardingový krok přidaný v tomto vydání prezentuje všechny tři jako oddělené rozbalovací nabídky přesně z tohoto důvodu.
Milý detail je cesta aktualizace. Jednorázová migrace zkopíruje output_language každého stávajícího uživatele do nového klíče app_language při prvním spuštění po aktualizaci a provider řeší jazyk přes řetězec fallbacků — app_language, pak output_language, pak 'en'. Takže uživatelé, kteří už aplikaci řekli, že chtějí španělské AI odpovědi, se probudili se španělským rozhraním, místo aby byli resetováni na angličtinu a nuceni hledat nastavení. Naplnit nové nastavení ze souvisejícího starého je malá laskavost, která stojí jednu migraci a ušetří každému aktualizujícímu drobnou otravu.
Onboardingový re-render, který nechtěl
Je tu jeden opravdový bug, který stojí za to vytáhnout z práce na i18n, protože je to React past, do které narazí každý, kdo dělá přepínání jazyka za běhu. Onboardingový průvodce staví některé své seznamy možností uvnitř useMemo. Když změníš jazyk přímo na kroku jazyka, rozhraní by se mělo okamžitě překreslit do nového jazyka — a neudělalo to, protože t nebylo v poli závislostí memoizace. Překladová funkce mění identitu, když se změní jazyk; pokud je tvá memoizovaná hodnota postavená z t, ale nezávisí na něm, React ti radostně předá zastaralou verzi v předchozím jazyce. Oprava se v logu objevuje dvakrát — jednou pro průvodce, jednou pro rozbalovací seznam v nastavení — což ti říká, že je to ten druh chyby, kterou uděláš na každém místě, kde memoizuješ přeložený obsah, dokud se nenaučíš vždy uvádět t.
Onboarding nesl i vrásku, kterou changelog nezmiňuje: protože tohle je white-label codebase, jsou tu dva onboardingové stromy k překladu — průvodce GeekBye a Pavleur — žijící pod paralelními jmennými prostory klíčů onboarding.* a onboarding.pavleur.*. Každý onboardingový string byl přeložen dvakrát, do dvou hlasů značky, napříč všemi dvaceti devíti jazyky.
Co build nevěděl, že mu chybí
Tady je ta část, která z tohohle dělá lekci místo checklistu. v1.8.3 neměl žádný automatický způsob, jak extrahovat hardcoded stringy, ani žádnou CI kontrolu parity klíčů napříč locale. Takže definice „hotovo" byla „někdo navštívil komponenty, které si pamatoval, a zabalil stringy, které viděl". Ta definice propouští.
Dva týdny po vydání přistál úklidový commit se zprávou "translate all hardcoded English strings across 10 components into 30 languages" (přelož všechny hardcoded anglické stringy v 10 komponentách do 30 jazyků). Deset komponent — formulář pro hlášení problémů, taby souhrnu a metrik, tab reportu, obsah transkripce a chatu, prompt o limitu využití, chatové zprávy, tlačítko pro kopírování kódu, plovoucí akční tlačítka — vyšlo ve v1.8.3 a stále mluvilo na všechny anglicky, v každém jazyce. Nikomu build nespadl. Žádný test nezčervenal. Německý uživatel prostě viděl angličtinu v tabu reportu a jediným detektorem byl člověk, který se na to nakonec podíval.
Táž absence vyprodukovala menší trapasy. Dánský překlad vyšel se špatným slovem — Luk application helt místo Luk applikationen helt — a byl zalátán v pozdějším vydání, protože nebyla žádná brána s rodilým recenzentem a pipeline neměla jak to vědět. Klíče „quit app" chyběly v počáteční dávce a byly doplněny o dny později. A každá jednotlivá funkce, která vyšla potom — preset modifikátorových kláves, ztlumení mikrofonu, recap čipy, průhlednost overlaye — za sebou navěky vlekla vlastní commit „přelož nové klíče do 29 locale", protože nic invariant nevynucovalo automaticky.
Nepořádek v commit zprávách můžeš dokonce změřit. Tatáž třicítka locale souborů je popisována, vydání za vydáním, jako „30 jazyků", „29 jazyků" a — v jednom commitu — „28 locale". Nic se nepřidalo ani neubralo; na každém tagu od v1.8.3 po v2 je třicet souborů. Číslo se posouvá, protože nebyl jediný zdroj pravdy pro „kolik jazyků dodáváme", takže každý autor commitu počítal ručně, někdy zahrnul angličtinu jako jazyk a někdy jako zdroj. Changelog, který neudrží vlastní počet stabilní, je malý, poctivý signál, že to, co popisuje, nevynucuje stroj.
Nášlapná mina pluralizace
Ještě jedna věc, která stojí za zmínku, ne proto, že se rozbila hlasitě, ale protože je to ten druh bugu, který tohle uspořádání zve a před kterým tě nevaruje. Pluralizace v těchto locale souborech se dělá ručně, s párovými klíči: meetings.meetingCount a meetings.meetingCountPlural, profiles.filesAttached a filesAttachedPlural. To je čisté anglické rozdělení jednotné/množné číslo. Je to také špatně pro část jazyků, které aplikace teď tvrdí, že podporuje. Ruština, polština a čeština mají tři nebo čtyři tvary množného čísla podle čísla — „1 soubor", „2 soubory", „5 souborů" a „21 souborů" mohou brát různé koncovky. Schéma dvou klíčů jednotné/množné to neumí vyjádřit, takže se ty počty vykreslují gramaticky špatně. i18next má pro přesně tohle skutečnou pluralizační mašinerii; ruční páry ji obcházejí a žádný commit tu mezeru neuznává. Je to pluralizační ekvivalent úniku hardcoded stringů: neviditelný pro build, viditelný jen pro rodilého mluvčího.
Tři věci, které nás toto vydání naučilo
- Knihovna je těch snadných 80 %; nástroje jsou těch těžkých 20 %. Zapojení
react-i18nexta hromadný překlad stringů je vyřešený problém. Držet třicet souborů navěky v paritě není — a potřebuje to extraktor pro hardcoded stringy a CI kontrolu chybějících klíčů, z nichž ti knihovna ani jedno nedodá. Postav je dřív, než prohlásíš „plný i18n", jinak jsi prohlásil invariant, který nemáš jak udržet. - Rozděl nastavení jazyka, která jsou skutečně různá. Jazyk rozhraní, jazyk transkripce a jazyk AI odpovědí jsou tři osy, a v1.8.3 měl pravdu, že dal každé vlastní klíč — a ještě větší pravdu, že nové naplnil ze souvisejícího starého migrací, takže aktualizace uživatele nic nestála.
- Počet ve tvém changelogu je metrika disciplíny. Když je tatáž sada souborů 28, 29 a 30 jazyků napříč třemi commity, problém není číslo — je to chybějící zdroj pravdy. Pokud tvé jazyky nepočítá stroj, nikdo je nepočítá dvakrát stejně.
Předchozí kapitolu příběhu v1 najdete v redesign dashboardu kolem jedné vlnové křivky (v1.8.2); a celý oblouk v anatomii dodávání softwaru k dokonalosti.