
Mengeluarkan Tiga Puluh Bahasa Tanpa Jaring Keselamatan
GeekBye v1.8.3 memasang react-i18next dan menterjemahkan seluruh aplikasi ke 30 bahasa. Bahagian library-nya rutin. Bahagian yang menarik ialah apa yang hilang: tiada pemeriksaan pariti kunci dan tiada extractor string — jadi bahasa Inggeris hardcoded terlepas masuk, sebuah salah taip bahasa Denmark termuat keluar, dan changelog tidak dapat bersepakat sama ada aplikasi bertutur 28, 29, atau 30 bahasa.
Sesetengah keluaran ialah sebuah ciri. GeekBye v1.8.3 kelihatan begitu — "aplikasi kini bertutur 30 bahasa" — tetapi ciri itu ialah bahagian yang mudah, dan bukan itu yang dibincangkan tulisan ini. Antara 17 dan 19 Februari 2026, dua pull request memasang react-i18next ke dalam aplikasi, merefaktor setiap string Inggeris hardcoded menjadi panggilan terjemahan, dan membungkus tiga puluh fail locale. Itu kerja sebenar, tetapi ia jenis kerja yang memang direka untuk dijadikan rutin oleh sebuah library. Kejuruteraan yang menarik ialah segala yang keluaran ini tidak bina — jaring keselamatan yang sepatutnya menangkap apa yang dikeluarkannya dalam keadaan rosak.
Pemasangannya ialah 80% yang mudah
Commit infrastruktur menambah react-i18next di atas i18next dan melakukan perkara yang konvensional: sebuah i18n/index.ts yang memanggil initReactI18next, mengimport secara statik ketiga-tiga puluh JSON locale, dan mendaftarkannya di bawah satu objek resources. Tiada lazy loading — setiap bahasa turut serta dalam bundle. String terjemahan tinggal di src/i18n/locales/*.json sebagai peta rata ber-namespace titik: sidebar.meetings, startMeeting.start, satu kunci untuk satu string.
Migrasi daripada bahasa Inggeris hardcoded kepada t('key') dilakukan dengan cara yang jujur, kumpulan komponen demi kumpulan komponen, dan anda boleh membaca sapuannya dalam log commit: sidebar, navigasi, dan chat dahulu; kemudian settings, login, dan onboarding; kemudian meetings, dashboard, toast, dan tooltip navbar. Setiap commit menggantikan satu batch string literal dengan panggilan terjemahan. Dua puluh sembilan fail bukan-Inggeris mendarat dalam satu commit — sebuah jatuhan sembilan ribu baris yang menterjemahkan sumber Inggeris ke segala-galanya daripada bahasa Bulgaria hingga Vietnam.
Tiada satu pun daripada itu sukar dilakukan dengan betul, kerana melakukannya dengan salah itu bising: sebuah provider yang hilang terhempas, sebuah JSON yang cacat gagal dihurai, sebuah import yang buruk mematahkan build. Library memberi anda pagar pelindung untuk kesilapan mekanikal. Yang tidak diberikannya ialah pagar pelindung untuk kesilapan yang benar-benar berlaku.
Tiga tetapan bahasa, dan mengapa itu betul
Sebelum kita sampai kepada apa yang rosak, ada satu perkara yang v1.8.3 lakukan dengan betul sepenuhnya, kerana ia sebuah perbezaan yang banyak aplikasi ratakan sedangkan tidak sepatutnya. Selepas keluaran ini, GeekBye mempunyai tiga tetapan bahasa yang bebas:
- Bahasa jawapan AI (
output_language) — bahasa apa yang digunakan pembantu untuk menjawab. Yang tertua antara ketiga-tiganya, sejak November 2025. - Bahasa transkrip (
transcriptLanguage) — bahasa apa yang digunakan enjin pertuturan untuk menyalin mikrofon anda. Dipasang beberapa keluaran lebih awal, di v1.7.6. - Bahasa aplikasi (
app_language) — bahasa bagi butang, menu, dan onboarding. Baharu di v1.8.3.
Ini benar-benar paksi yang berbeza. Seorang pembangun di Berlin mungkin mahu antara muka bahasa Jerman, jawapan AI bahasa Inggeris (kerana itu bahasa dokumen yang mereka tampal), dan transkripsi bahasa Inggeris (kerana mesyuaratnya dalam bahasa Inggeris). Melebur kesemuanya menjadi satu tetapan "bahasa" akan salah bagi orang itu, dan langkah onboarding yang ditambah dalam keluaran ini memaparkan ketiga-tiganya sebagai dropdown berasingan justeru atas sebab itu.
Sentuhan yang menyenangkan ialah laluan naik tarafnya. Sebuah migrasi sekali jalan menyalin output_language setiap pengguna sedia ada ke kunci app_language yang baharu pada pelancaran pertama selepas mengemas kini, dan provider menyelesaikan bahasa melalui rantaian fallback — app_language, kemudian output_language, kemudian 'en'. Jadi pengguna yang telah pun memberitahu aplikasi bahawa mereka mahu jawapan AI bahasa Sepanyol terjaga dengan antara muka bahasa Sepanyol, dan bukannya diset semula ke bahasa Inggeris dan terpaksa mencari-cari tetapan itu. Menyemai keutamaan baharu daripada keutamaan lama yang berkaitan ialah satu kebaikan kecil yang berkos satu migrasi dan menyelamatkan setiap pengguna yang menaik taraf daripada satu kerengsaan kecil.
Render semula onboarding yang enggan
Ada satu bug sebenar yang berbaloi diangkat daripada kerja i18n ini, kerana ia sebuah perangkap React yang akan ditemui sesiapa sahaja yang melakukan penukaran bahasa pada masa jalan. Wizard onboarding membina sebahagian daripada senarai pilihannya di dalam sebuah useMemo. Apabila anda menukar bahasa anda pada langkah bahasa itu sendiri, UI sepatutnya melukis semula dalam bahasa baharu serta-merta — dan ia tidak, kerana t tiada dalam dependency array milik memo itu. Fungsi terjemahan bertukar identiti apabila bahasa berubah; jika nilai ter-memoize anda dibina daripada t tetapi tidak bergantung padanya, React dengan gembira menyerahkan kepada anda versi basi daripada bahasa sebelumnya. Pembetulan itu muncul dua kali dalam log — sekali untuk wizard, sekali untuk senarai dropdown settings — yang memberitahu anda bahawa ia jenis kesilapan yang anda buat di setiap tempat anda memoize kandungan terjemahan sehingga anda belajar untuk sentiasa menyenaraikan t.
Onboarding juga membawa satu kedutan yang tidak disebut changelog: kerana ini sebuah codebase white-label, ada dua pokok onboarding untuk diterjemah — sebuah wizard GeekBye dan sebuah wizard Pavleur — yang tinggal di bawah namespace kunci selari onboarding.* dan onboarding.pavleur.*. Setiap string onboarding diterjemah dua kali, ke dalam dua suara jenama, merentasi kesemua dua puluh sembilan bahasa.
Apa yang build tidak tahu ia kehilangan
Inilah bahagian yang menjadikan ini sebuah pengajaran dan bukannya sebuah checklist. v1.8.3 tiada cara automatik untuk mengekstrak string hardcoded dan tiada pemeriksaan CI untuk pariti kunci merentasi locale. Jadi takrifan "siap" ialah "seseorang melawat komponen yang dia ingat dan membalut string yang dia nampak." Takrifan itu bocor.
Dua minggu selepas keluaran, sebuah commit pembersihan mendarat dengan mesej "translate all hardcoded English strings across 10 components into 30 languages." Sepuluh komponen — borang lapor-isu, tab ringkasan dan metrik, tab laporan, kandungan transkrip dan chat, gesaan had-penggunaan, mesej chat, butang salin-kod, butang tindakan terapung — telah dikeluarkan di v1.8.3 sambil masih bertutur bahasa Inggeris kepada semua orang, dalam setiap bahasa. Build sesiapa pun tidak gagal. Tiada ujian bertukar merah. Seorang pengguna Jerman sekadar melihat bahasa Inggeris di tab laporan, dan satu-satunya pengesan ialah seorang manusia yang akhirnya memandangnya.
Ketiadaan yang sama menghasilkan rasa malu yang lebih kecil. Sebuah terjemahan Denmark dikeluarkan dengan perkataan yang salah — Luk application helt dan bukannya Luk applikationen helt — dan ditampal dalam keluaran kemudian, kerana tiada pintu penyemak penutur asli dan tiada cara untuk pipeline mengetahuinya. Kunci "quit app" hilang daripada batch awal dan diisi-semula beberapa hari kemudian. Dan setiap ciri yang dikeluarkan selepasnya — sebuah pratetap kekunci pengubah, senyapkan mikrofon, cip rekap, kelegapan overlay — menyeret commit "terjemah kunci baharu ke 29 locale"-nya sendiri di belakangnya, selama-lamanya, kerana tiada apa-apa yang menguatkuasakan invarian itu secara automatik.
Anda malah boleh mengukur kekacauannya dalam mesej commit. Tiga puluh fail locale yang sama itu digambarkan, keluaran demi keluaran, sebagai "30 bahasa," "29 bahasa," dan — dalam satu commit — "28 locale." Tiada apa-apa ditambah atau dibuang; ada tiga puluh fail pada setiap tag daripada v1.8.3 hingga v2. Nombornya hanyut kerana tiada satu sumber kebenaran untuk "berapa banyak bahasa yang kita keluarkan," jadi setiap penulis commit mengira dengan tangan, kadangkala memasukkan bahasa Inggeris sebagai sebuah bahasa dan kadangkala sebagai sumbernya. Sebuah changelog yang tidak dapat mengekalkan kiraannya sendiri stabil ialah isyarat kecil lagi jujur bahawa perkara yang digambarkannya tidak sedang dikuatkuasakan oleh sesebuah mesin.
Ranjau pluralisasi
Satu perkara lagi yang berbaloi ditandakan, bukan kerana ia rosak dengan bising tetapi kerana ia jenis bug yang dijemput oleh susunan ini dan tidak akan memberi anda amaran. Pluralisasi dalam fail locale ini dilakukan secara manual, dengan kunci berpasangan: meetings.meetingCount dan meetings.meetingCountPlural, profiles.filesAttached dan filesAttachedPlural. Itu sebuah pemisahan tunggal/jamak Inggeris yang kemas. Ia juga salah bagi sebahagian daripada bahasa yang kini didakwa disokong aplikasi. Bahasa Rusia, Poland, dan Czech mempunyai tiga atau empat bentuk jamak bergantung pada nombornya — "1 file," "2 files," "5 files," dan "21 files" boleh mengambil pengakhiran perkataan yang berbeza. Skema dua-kunci tunggal/jamak tidak dapat menyatakan itu, jadi kiraan-kiraan itu terpapar salah dari segi tatabahasa. i18next mempunyai jentera jamak sebenar tepat untuk ini; pasangan manual itu memintasnya, dan tiada commit yang mengakui jurang itu. Ia padanan pluralisasi bagi kebocoran string-hardcoded: tidak kelihatan kepada build, kelihatan hanya kepada penutur asli.
Tiga perkara yang diajarkan oleh keluaran ini
- Library ialah 80% yang mudah; perkakas ialah 20% yang sukar. Memasang
react-i18nextdan menterjemahkan string secara pukal ialah masalah yang telah diselesaikan. Mengekalkan tiga puluh fail dalam pariti selama-lamanya tidak — dan ia memerlukan sebuah extractor untuk string hardcoded dan sebuah pemeriksaan CI untuk kunci yang hilang, yang kedua-duanya tidak dikeluarkan oleh sebuah library untuk anda. Bina itu sebelum anda mendakwa "i18n penuh," atau anda telah mendakwa sebuah invarian yang anda tiada cara untuk pegang. - Asingkan tetapan bahasa yang benar-benar berbeza. Bahasa UI, bahasa transkrip, dan bahasa jawapan AI ialah tiga paksi, dan v1.8.3 betul memberi setiap satu kuncinya sendiri — dan lebih betul lagi menyemai yang baharu daripada yang lama yang berkaitan melalui migrasi, supaya menaik taraf tidak berkos apa-apa kepada pengguna.
- Kiraan changelog anda ialah metrik disiplin. Apabila set fail yang sama ialah 28, 29, dan 30 bahasa merentasi tiga commit, nombor itu bukan masalahnya — sumber kebenaran yang hilang itulah masalahnya. Jika sesebuah mesin tidak mengira bahasa anda, tiada siapa mengiranya dengan cara yang sama dua kali.
Untuk bab sebelumnya dalam kisah v1, mereka bentuk semula dashboard di sekitar satu graf gelombang (v1.8.2); dan untuk keseluruhan lengkungnya, anatomi mengeluarkan perisian hingga ke kesempurnaan.