
Güvenlik Ağı Olmadan Otuz Dil Sevk Etmek
GeekBye v1.8.3, react-i18next'i bağladı ve tüm uygulamayı 30 dile çevirdi. Kütüphane kısmı rutindi. İlginç olan kısım eksik olan şeydi: ne bir anahtar-paritesi kontrolü ne de bir string çıkarıcı vardı — böylece hardcoded İngilizce sızdı, bir Danca yazım hatası sevk edildi, ve changelog uygulamanın 28, 29 mu yoksa 30 dil mi konuştuğunda anlaşamadı.
Bazı sürümler bir özelliktir. GeekBye v1.8.3 öyle görünüyor — "uygulama artık 30 dil konuşuyor" — ama özellik kolay kısımdı, ve bu yazı onunla ilgili değil. 17-19 Şubat 2026 arasında, iki pull request react-i18next'i uygulamaya bağladı, her hardcoded İngilizce string'i bir çeviri çağrısına dönüştürdü, ve otuz locale dosyasını paketledi. Bu gerçek bir iş, ama bir kütüphanenin rutinleştirmek için tasarlandığı türden bir iş. İlginç mühendislik, sürümün inşa etmediği her şey — kırık sevk ettiği şeyi yakalayacak olan güvenlik ağı.
Bağlantı kurmak kolay olan %80'di
Altyapı commit'i i18next üzerine react-i18next ekledi ve alışıldık olanı yaptı: initReactI18next'i çağıran, otuz locale JSON'ının hepsini statik olarak içe aktaran ve onları tek bir resources nesnesi altında kaydeden bir i18n/index.ts. Lazy loading yok — her dil bundle içinde geliyor. Çeviri stringleri src/i18n/locales/*.json içinde düz, noktayla ad-uzayı verilmiş haritalar olarak yaşıyor: sidebar.meetings, startMeeting.start, bir anahtar bir string'e.
Hardcoded İngilizce'den t('key')'e geçiş dürüst yoldan yapıldı, bileşen grubu bileşen grubu, ve süpürmeyi commit log'unda okuyabilirsin: önce sidebar, navigasyon ve chat; sonra settings, login ve onboarding; sonra meetings, dashboard, toast'lar ve navbar tooltip'leri. Her commit bir grup düz string'i çeviri çağrılarıyla değiştirdi. Yirmi dokuz İngilizce-olmayan dosya tek bir commit'te indi — Bulgarcadan Vietnamcaya kadar her şeye İngilizce kaynağı çeviren dokuz bin satırlık bir bırakma.
Bunların hiçbirini doğru yapmak zor değil, çünkü yanlış yapmak gürültülüdür: eksik bir provider çöker, bozuk bir JSON parse edilmez, kötü bir import build'i kırar. Kütüphane sana mekanik hatalar için korkuluklar verir. Sana vermediği şey, gerçekten olan hata için bir korkuluktur.
Üç dil ayarı, ve bunun neden doğru olduğu
Neyin bozulduğuna gelmeden önce, v1.8.3'ün tam olarak doğru yaptığı bir şey, çünkü bu birçok uygulamanın düzleştirdiği ve düzleştirmemesi gereken bir ayrım. Bu sürümden sonra, GeekBye'ın üç bağımsız dil ayarı var:
- AI-yanıt dili (
output_language) — asistanın hangi dilde yanıt verdiği. Üçünün en eskisi, Kasım 2025'ten. - Transcript dili (
transcriptLanguage) — konuşma motorunun mikrofonunu hangi dilde yazıya döktüğü. Birkaç sürüm önce, v1.7.6'da döşendi. - Uygulama dili (
app_language) — düğmelerin, menülerin ve onboarding'in dili. v1.8.3'te yeni.
Bunlar gerçekten farklı eksenler. Berlin'deki bir geliştirici Almanca bir arayüz, İngilizce AI yanıtları (çünkü yapıştırdığı dokümanların dili bu) ve İngilizce transkripsiyon (çünkü toplantı İngilizce) isteyebilir. Bunları tek bir "dil" ayarına indirmek o kişi için yanlış olurdu, ve bu sürümde eklenen onboarding adımı tam da bu nedenle üçünü de ayrı açılır menüler olarak sunuyor.
Hoş dokunuş yükseltme yolu. Tek seferlik bir migration, güncellemeden sonraki ilk açılışta her mevcut kullanıcının output_language'ini yeni app_language anahtarına kopyalıyor, ve provider dili bir geri-çekilme zinciriyle çözüyor — app_language, sonra output_language, sonra 'en'. Böylece uygulamaya İspanyolca AI yanıtları istediklerini zaten söylemiş kullanıcılar, İngilizceye sıfırlanıp ayarı aramak zorunda kalmak yerine İspanyolca bir arayüzle uyandılar. Yeni bir tercihi ilişkili eski bir tercihten tohumlamak, bir migration'a mal olan ve her yükselten kullanıcıya küçük bir sıkıntıyı kaydeden küçük bir naziklik.
Bir türlü olmayan onboarding yeniden-render'ı
i18n çalışmasından çıkarmaya değer gerçek bir bug var, çünkü çalışma zamanında dil değiştiren herkesin çarpacağı bir React tuzağı. Onboarding sihirbazı bazı seçenek listelerini bir useMemo içinde kuruyor. Dilini dil adımının kendisinde değiştirdiğinde, arayüzün hemen yeni dilde yeniden çizilmesi gerekiyor — ve çizmedi, çünkü t memo'nun bağımlılık dizisinde değildi. Çeviri fonksiyonu dil değiştiğinde kimlik değiştirir; memoize edilmiş değerin t'den kuruluysa ama ona bağlı değilse, React sana seve seve bayat, önceki-dildeki sürümü verir. Düzeltme log'da iki kez görünüyor — bir kez sihirbaz için, bir kez settings açılır listesi için — ki bu da sana bunun, her t'yi listelemeyi öğrenene kadar çevrilmiş içeriği memoize ettiğin her yerde yaptığın türden bir hata olduğunu söylüyor.
Onboarding, changelog'un bahsetmediği bir kırışıklık da taşıyordu: bu bir white-label kod tabanı olduğundan, çevrilecek iki onboarding ağacı var — bir GeekBye sihirbazı ve bir Pavleur sihirbazı — paralel onboarding.* ve onboarding.pavleur.* anahtar ad-uzaylarının altında yaşıyorlar. Her onboarding string'i, iki marka sesine, yirmi dokuz dilin hepsine, iki kez çevrildi.
Build'in eksik olduğunu bilmediği şey
İşte bunu bir kontrol listesi yerine bir ders yapan kısım. v1.8.3'ün hardcoded stringleri çıkarmak için otomatik bir yolu ve locale'ler arası anahtar paritesi için bir CI kontrolü yoktu. Yani "bitti"nin tanımı "biri hatırladığı bileşenleri ziyaret etti ve gördüğü stringleri sardı" idi. Bu tanım sızdırır.
Sürümden iki hafta sonra, "translate all hardcoded English strings across 10 components into 30 languages." mesajıyla bir temizlik commit'i indi. On bileşen — sorun-bildirim formu, özet ve metrik sekmeleri, rapor sekmesi, transcript ve chat içeriği, kullanım-limiti istemi, chat mesajları, kodu-kopyala düğmesi, yüzen eylem düğmeleri — v1.8.3'te hâlâ herkese, her dilde İngilizce konuşarak sevk edilmişti. Kimsenin build'i başarısız olmadı. Hiçbir test kırmızıya dönmedi. Alman bir kullanıcı rapor sekmesinde sadece İngilizce gördü, ve tek dedektör sonunda ona bakan bir insandı.
Aynı yokluk daha küçük utançları da üretti. Bir Danca çeviri yanlış sözcükle sevk edildi — Luk applikationen helt yerine Luk application helt — ve daha sonraki bir sürümde yamalandı, çünkü ne bir ana dil gözden geçiren kapısı ne de pipeline'ın bunu bilmesinin bir yolu vardı. "Quit app" anahtarları ilk partide eksikti ve günler sonra geri dolduruldu. Ve sonradan sevk edilen her bir özellik — bir değiştirici-tuş ön ayarı, mikrofon susturma, özet çipleri, overlay opaklığı — kendi "yeni anahtarları 29 locale'e çevir" commit'ini ardında sürükledi, sonsuza dek, çünkü hiçbir şey değişmezi otomatik olarak dayatmadı.
Düzensizliği commit mesajlarında bile ölçebilirsin. Aynı otuz locale dosyası, sürümden sürüme, "30 dil," "29 dil," ve — bir commit'te — "28 locale" olarak tanımlanıyor. Hiçbir şey eklenmedi ya da çıkarılmadı; v1.8.3'ten v2'ye kadar her tag'de otuz dosya var. Sayı kayıyor çünkü "kaç dil sevk ediyoruz" için tek bir doğruluk kaynağı yoktu, bu yüzden her commit yazarı elle saydı, kimi zaman İngilizceyi bir dil kimi zaman kaynak olarak dahil ederek. Kendi sayısını sabit tutamayan bir changelog, tarif ettiği şeyin bir makine tarafından dayatılmadığının küçük, dürüst bir işaretidir.
Çoğullaştırma tuzağı
İşaret etmeye değer bir şey daha, gürültülü bir şekilde bozulduğu için değil, bu kurulumun davet ettiği ve seni uyarmayacağı türden bir bug olduğu için. Bu locale dosyalarında çoğullaştırma elle yapılıyor, eşleştirilmiş anahtarlarla: meetings.meetingCount ve meetings.meetingCountPlural, profiles.filesAttached ve filesAttachedPlural. Bu, temiz bir İngilizce tekil/çoğul ayrımı. Aynı zamanda uygulamanın artık desteklediğini iddia ettiği dillerin bir kısmı için yanlış. Rusça, Lehçe ve Çekçenin sayıya göre üç ya da dört çoğul biçimi var — "1 file," "2 files," "5 files," ve "21 files" farklı sözcük sonları alabilir. İki anahtarlı bir tekil/çoğul şeması bunu ifade edemez, bu yüzden o sayılar gramer açısından yanlış görünür. i18next'in tam da bunun için gerçek çoğul makinesi var; manuel çiftler onu atlatıyor, ve hiçbir commit bu boşluğu kabul etmiyor. Bu, hardcoded-stringler sızıntısının çoğullaştırma karşılığı: build için görünmez, yalnızca bir ana dil konuşucusu için görünür.
Bu sürümün bize öğrettiği üç şey
- Kütüphane kolay olan %80'dir; araç zor olan %20'dir.
react-i18next'i bağlamak ve stringleri toplu çevirmek çözülmüş bir problem. Otuz dosyayı sonsuza dek parite içinde tutmak değil — ve bu, hardcoded stringler için bir çıkarıcı ve eksik anahtarlar için bir CI kontrolü gerektirir, ki bir kütüphane bunların hiçbirini senin için sevk etmez. Onları "tam i18n" iddia etmeden önce inşa et, yoksa tutmanın hiçbir yolu olmayan bir değişmezi iddia etmiş olursun. - Gerçekten farklı olan dil ayarlarını ayır. Arayüz dili, transcript dili ve AI-yanıt dili üç eksendir, ve v1.8.3 her birine kendi anahtarını vermekte haklıydı — ve yenisini ilişkili eski bir ayardan migration ile tohumlamakta daha da haklıydı, böylece yükseltmek kullanıcılara hiçbir şeye mal olmadı.
- Changelog'unun sayısı bir disiplin metriğidir. Aynı dosya kümesi üç commit boyunca 28, 29 ve 30 dil olduğunda, sorun sayı değil — eksik olan doğruluk kaynağıdır. Bir makine dillerini saymıyorsa, kimse onları iki kez aynı şekilde saymıyordur.
v1 hikâyesinin bir önceki bölümü için, dashboard'u tek bir dalga grafiği etrafında yeniden tasarlamak (v1.8.2); tüm yay için de yazılımı kusursuzluğa kadar sevk etmenin anatomisi.