Sohbetle oluşturulan uygulamalar için uluslararasılaştırma mimarisi: kararlı dize anahtarları, çoğul kuralları ve web ile mobilde tutarlı kalan tek bir çeviri iş akışı tanımlayın.

İlk bozulan şey kod değil. Sözcüklerdir.
Sohbetle oluşturulan uygulamalar genelde hızlı bir prototip olarak başlar: “Kaydet yazan bir buton ekle” yazarsınız, UI çıkar ve devam edersiniz. Haftalar sonra İspanyolca ve Almanca eklemek istediğinizde, o “geçici” etiketlerin ekranlarda, bileşenlerde, e-postalarda ve hata mesajlarında dağınık olduğunu görürsünüz.
Metin değişiklikleri kod değişikliklerinden daha sık olur. Ürün isimleri yeniden adlandırılır, yasal metinler değişir, onboarding yeniden yazılır ve destek daha açıklayıcı hata mesajları ister. Metin UI kodunun içine doğrudan yerleştirildiyse, her küçük ifade değişikliği riskli bir sürüm haline gelir ve aynı fikrin farklı yerlerde farklı şekilde ifade edildiği yerleri kaçırırsınız.
İşte çeviri borcu biriktiğinin erken belirtileri:
Gerçekçi bir örnek: Koder.ai ile basit bir CRM inşa edersiniz. Web uygulaması “Deal stage” der, mobil uygulama “Pipeline step” der, bir hata toast'ı “Invalid status” der. Üçü de çevrilmiş olsa bile, kullanıcılar kavramların eşleşmediğini hissettiği için uygulamanın tutarsız olduğunu düşünür.
“Tutarlı” demek her yerde aynı karakterler olması demek değildir. Anlamı şudur:
Metni süsleme değil, ürün verisi olarak ele aldığınızda diller eklemek telaş olmaktan çıkar ve düzenli bir süreç haline gelir.
Uluslararasılaştırma (i18n), bir uygulamanın yeniden yazım gerektirmeden birçok dili desteklemesine yönelik yaptığınız çalışmadır. Lokalizasyon (l10n) ise belirli bir dil ve bölge için gerçek içeriktir; örneğin Kanada Fransızcası için doğru kelimeler, tarih biçimleri ve üslup.
Hedeflenecek basit bir amaç: kullanıcıya dönük her metin parçası, UI koduna doğrudan yazılmak yerine sabit bir anahtar ile seçilsin. Bir cümleyi değiştirmek için bir React bileşenini veya bir Flutter widget'ını açmak zorunda kalmıyorsanız doğru yoldasınız. Bu, sohbetle oluşturulan uygulamalar için uluslararasılaştırma mimarisinin çekirdeğidir; çünkü sohbet sırasında üretilen sabit metni kazara yayına almak kolaydır.
Kullanıcıya dönük metin, birçok ekip için beklenenden daha geniştir. Butonlar, etiketler, doğrulama hataları, boş durumlar, onboarding ipuçları, push bildirimleri, e-postalar, PDF çıktıları ve kullanıcı görebileceği ya da duyabileceği her mesaj dahildir. Genelde iç loglar, veritabanı sütun adları, analiz olay kimlikleri, özellik bayrakları veya yalnızca yöneticiye yönelik hata çıktıları buna dahil değildir.
Çeviriler nerede yaşamalı? Pratikte genelde hem frontend hem backend vardır, ancak net bir sınırla.
Kaçınılması gereken hata sorumlulukları karıştırmaktır. Eğer backend UI hataları için tamamen yazılmış İngilizce cümleler döndürürse, frontend bunları temizce yerelleştiremez. Daha iyi bir desen: backend bir hata kodu (ve gerekliyse güvenli parametreler) döndürsün, istemci o kodu yerel bir mesaja eşlesin.
Metin sahipliği bir ürün kararıdır, teknik bir detay değil. Kimlerin kelimeleri değiştirebileceğini ve üslubu onaylayacağını erken belirleyin.
Ürün metinden sorumluysa, çevirileri içerik gibi ele alın: versiyonlayın, inceleyin ve ürünün değişiklik istemesi için güvenli bir yol sağlayın. Mühendislik metinden sorumluysa, yeni bir UI dizesinin yayımlanmadan önce bir anahtar ve varsayılan çeviri ile gelmesi kuralını koyun.
Örnek: kayıt akışınız üç farklı ekranda “Create account” diyorsa, bunu her yerde kullanılan tek bir anahtar yapın. Bu anlamı tutarlı kılar, çevirmenleri hızlandırır ve küçük ifade değişikliklerinin sonraki çok ekranlı temizlik işine dönüşmesini engeller.
Anahtarlar UI ile çevirileriniz arasındaki sözleşmedir. Bu sözleşme sürekli değişirse, eksik metinler, acele düzeltmeler ve web ile mobil arasında tutarsız ifadeler elde edersiniz. Sohbetle oluşturulan uygulamalar için iyi bir uluslararasılaştırma mimarisi bir kuralla başlar: anahtarlar anlamı tanımlamalı, mevcut İngilizce cümleyi değil.
Tam metin (örneğin "Pay now") yerine stabil ID'ler kullanın (örneğin billing.invoice.payNow). Cümle anahtarları, biri ifadeyle oynadığında, noktalama veya büyük/küçük harf değiştiğinde bozulur.
Okunabilir kalan pratik bir desen: ekran (veya alan) + bileşen + niyet. Sıkıcı ve tahmin edilebilir tutun.
Örnekler:
auth.login.titleauth.login.emailLabelbilling.checkout.payButtonnav.settingserrors.network.offlineBir anahtarı yeniden kullanma mı yoksa yenisini oluşturma mı gerektiğine şu soruyu sorarak karar verin: “Her yerde anlam tamamen aynı mı?” Gerçekten genel eylemler için anahtarları yeniden kullanın; ancak bağlam değişiyorsa anahtarları ayırın. Örneğin, profil ekranındaki “Save” basit bir eylem olabilirken, karmaşık bir editördeki “Save” bazı dillerde daha özel bir tona ihtiyaç duyabilir.
Paylaşılan UI metinlerini ayrılmış ad alanlarında tutun ki ekranlar arasında çoğaltılmasın. İyi çalışan ortak kovalar:
common.actions.* (save, cancel, delete)common.status.* (loading, success)common.fields.* (search, password)errors.* (validation, network)nav.* (tabs, menu items)Deyim değişse bile anlam aynıysa, anahtarı koruyun ve sadece çevrilmiş değerleri güncelleyin. Bu sabit ID'lerin tüm amacı budur. Anlam değiştiyse (ince de olsa), yeni bir anahtar oluşturun ve eskiyi kullanılmadığını doğrulayana kadar bırakın. Bu, eski bir çevirinin teknik olarak var olmasına rağmen yanlış olmasını önler.
Koder.ai benzeri bir akıştan küçük bir örnek: sohbet hem React web uygulaması hem Flutter mobil uygulaması üretir. Eğer ikisi common.actions.save kullanırsa, her yerde tutarlı çeviriler elde edersiniz. Ama web profile.save, mobil account.saveButton kullanırsa, bugün İngilizce aynı görünse bile zaman içinde sürüklenecektir.
Kaynak dilinizi (genelde İngilizce) tek doğru kaynak olarak ele alın. Onu tek bir yerde tutun, kod gibi inceleyin ve dizelerin rastgele bileşenlerde “şimdilik” görünmesine izin vermeyin. Bu, gömülü sabit UI metninden ve daha sonra yeniden çalışmadan kaçınmanın en hızlı yoludur.
Basit bir kural yardımcı olur: uygulama yalnızca i18n sisteminden gelen metni gösterebilir. Yeni metin gerekiyorsa, önce bir anahtar ve varsayılan mesaj eklenir, sonra UI o anahtarı kullanır. Bu, sohbetle oluşturulan uygulamalar için uluslararasılaştırma mimarisini sabit tutar, özellikler bir yerden diğerine taşındığında bile.
Hem web hem mobil yayınlıyorsanız, bir ortak anahtar kataloğu ve ekiplerin birbirinin ayağına basmadan çalışabileceği alan istersiniz. Pratik bir düzen:
Platformlar arasında anahtarları aynı tutun, implementasyon farklı olsa bile (web için React, mobil için Flutter). Koder.ai gibi bir platform kullanıyorsanız, sohbetten her iki uygulamayı da üretirken kaynak kodu dışa aktarmak, her iki projenin de aynı anahtar isimlerine ve mesaj formatına işaret etmesi durumunda bakımını kolaylaştırır.
Çeviriler zaman içinde değişir. Değişiklikleri ürün değişikliği gibi ele alın: küçük, incelenmiş ve takip edilebilir olsun. İyi bir inceleme anlam ve yeniden kullanımı denetler, sadece yazım değil.
Anahtarların takılmasını önlemek için, anahtarları özelliklere (billing., auth.) sahip olun ve kelime değişti diye anahtarları yeniden adlandırmayın. Anahtarlar tanımlayıcıdır, metin değildir.
Çoğul kuralları dilden dile değişir; bu yüzden İngilizcenin (1 vs diğerleri) basit deseni çabuk bozulur. Bazı diller 0, 1, 2-4 gibi ayrı formlara sahiptir. Diğerleri tüm cümleyi değiştirir, sadece ismi değil. Çoğul mantığını UI içinde if-else ile yerleştirirseniz, kopyalanmış metinler ve kaçırılan uç durumlar yaşarsınız.
Daha güvenli bir yaklaşım, her fikir için esnek bir mesaj tutmak ve i18n katmanının doğru formu seçmesine izin vermektir. ICU tarzı mesajlar bunun için yapılmıştır. Dilbilgisi kararlarını bileşenler yerine çeviride tutarlar.
İnsanların unuttuğu durumları kapsayan küçük bir örnek:
\nitemsCount = \"{count, plural, =0 {No items} one {# item} other {# items}}\"\n
Bu tek anahtar 0, 1 ve diğerlerini kapsar. Çevirmenler kendi dilleri için doğru çoğul formlarını buraya koyar, sizin koda dokunmanız gerekmez.
Cinsiyet veya role dayalı ifadeye ihtiyaç duyduğunuzda, ürün gerçekten gerektirmedikçe welcome_male ve welcome_female gibi ayrı anahtarlar oluşturmayın. Cümleyi tek parça tutmak için select kullanın:
\nwelcomeUser = \"{gender, select, female {Welcome, Ms. {name}} male {Welcome, Mr. {name}} other {Welcome, {name}}}\"\n
Dilsel hallerle (grammatical cases) kendinizi köşeye sıkıştırmamak için cümleleri mümkün olduğunca tamamlanmış tutun. Parçaları birbirine eklemeyin: "{count} " + t('items') gibi çünkü birçok dilde kelime sırası böyle yeniden düzenlenemez. Sayıyı, ismi ve çevresindeki kelimeleri içeren tek bir mesaj tercih edin.
Sohbetle oluşturulan uygulamalarda (Koder.ai projeleri dahil) işe yarayan basit bir kural: bir cümlede sayı, kişi veya durum varsa, baştan itibaren ICU yapısı kullanın. Bu başlangıçta biraz maliyetlidir ama sonra çok fazla çeviri borcunu önler.
React web uygulamanız ve Flutter mobil uygulamanız kendi çeviri dosyalarını tutuyorsa zamanla farklılaşırlar. Aynı buton farklı kelimelere sahip olur, bir anahtar webde bir anlamı mobilde başka bir anlamı verir ve destek kayıtları “uygulama X diyor ama web Y diyor” demeye başlar.
En basit çözüm en önemlisidir: tek bir doğruluk kaynağı formatı seçin ve onu kod gibi ele alın. Çoğu ekip için bu, her iki platformun da tükettiği tek bir paylaşılan locale dosyası seti (örneğin ICU tarzı mesajlar kullanan JSON) demektir. Sohbet ve üreticilerle uygulama inşa ederken bu daha da önem kazanır; çünkü yeni metinleri kazara iki yerde oluşturmak kolaydır.
Pratik bir kurulum küçük bir “i18n paketi” veya klasör içerir:
React ve Flutter tüketici olur. Yeni anahtarları yerel olarak icat etmemelidirler. Koder.ai tarzı bir iş akışında (React web, Flutter mobil), her iki istemciyi aynı anahtar setinden üretebilir ve değişiklikleri diğer kod değişiklikleri gibi inceleyebilirsiniz.
Backend uyumu aynı hikâyenin parçasıdır. Hatalar, bildirimler ve e-postalar Go içinde elle yazılmış İngilizce dizeler olmamalıdır. Bunun yerine, stabil hata kodları (örneğin auth.invalid_password) ve güvenli parametreler döndürün. İstemciler sonra kodları çeviriye eşler. Sunucu tarafı e-postalar için sunucu aynı anahtarları ve locale dosyalarını kullanarak şablonları render edebilir.
Küçük bir kural kitabı oluşturun ve kod incelemede uygulayın:
Çift anlamlı anahtarları önlemek için çevirmenler ve gelecekteki siz için bir “açıklama” alanı (veya yorum dosyası) ekleyin. Örnek: billing.trial_days_left bunun banner olarak mı, e-posta olarak mı gösterildiğini açıklamalı. Bu küçük not genelde “yeterince yakın” yeniden kullanımını durdurur ve çeviri borcunu önler.
Bu tutarlılık, sohbetle oluşturulan uygulamalar için uluslararasılaştırma mimarisinin omurgasıdır: bir paylaşılan kelime hazinesi, birçok yüzey ve bir sonraki dili yayına alırken sürpriz yok.
Sohbetle oluşturulan uygulamalar için iyi bir uluslararasılaştırma mimarisi basit başlar: bir mesaj anahtar seti, bir doğruluk kaynağı ve web ile mobil için aynı kurallar. Hızlı inşa ediyorsanız (örneğin Koder.ai ile), bu yapı hızı korur ama çeviri borcu yaratmaz.
Yerel dilleri erken seçin ve bir çeviri eksik olduğunda ne olacağını kararlaştırın. Yaygın seçim: kullanıcının tercih ettiği dili gösterin, yoksa İngilizce'ye geri dönün ve eksik anahtarları bir sonraki sürümden önce düzeltmek için loglayın.
Sonra bunu uygulayın:
billing.plan_name.pro veya auth.error.invalid_password. Aynı anahtarları her yerde tutun.t("key") kullanın. Flutter'da benzer biçimde bir lokalizasyon sarıcı ve widget'larda anahtar tabanlı arama kullanın. Amaç aynı anahtarlar, aynı kütüphane olması değil."{count, plural, one {# file} other {# files}}" ve "Hello, {name}" gibi ICU tarzı mesajlar kullanın. Bu, ekranda if (count === 1) gibi geçici çözümler olmasını engeller.Son olarak, daha uzun kelimelere sahip bir dili (Almanca klasik örnek) ve farklı noktalama kullanan bir dili test edin. Bu, buton taşmalarını, kötü sarılan başlıkları ve İngilizce kelime uzunluğuna dayalı düzen varsayımlarını hızlıca ortaya çıkarır.
Çevirileri paylaşılan bir klasörde (veya oluşturulan paket olarak) tutup metin değişikliklerini kod değişikliği gibi ele alırsanız, web ve mobil uygulamalar hızla inşa edilirken bile tutarlı kalır.
Çevrilmiş UI dizeleri sorunun yalnızca yarısıdır. Çoğu uygulama ayrıca tarihler, fiyatlar, sayılar ve isimler gibi değişen değerler gösterir. Bu değerleri düz metin gibi ele alırsanız yanlış biçimler, hatalı saat dilimleri ve birçok dilde garip cümleler elde edersiniz.
Önce sayıları, para birimlerini ve tarihleri locale kurallarına göre biçimlendirin, özel kod yazmayın. Fransa'daki bir kullanıcı “1 234,50 €” beklerken, ABD'deki kullanıcı “$1,234.50” bekler. Aynı durum tarihler için de geçerli: “03/04/2026” belirsizdir, ama locale formatlaması bunu netleştirir.
Saat dilimleri sonraki tuzaktır. Sunucular genelde zaman damgalarını nötr bir biçimde (genelde UTC) saklamalıdır, ama kullanıcılar kendi saat dilimlerinde zaman görmek ister. Örneğin: 23:30 UTC'de oluşturulan bir sipariş Tokyo'daki biri için “yarın” olabilir. Her ekran için bir kural belirleyin: kişisel etkinliklerde kullanıcı yerel zamanını gösterin, mağaza teslim pencereleri gibi iş saatleri için sabit bir iş saat dilimi gösterin (ve bunu açıkça etiketleyin).
Çevirilmiş parçaları birleştirerek cümleler oluşturmayın. Bu dilbilgisini bozar çünkü kelime sırası dilden dile değişir. Şunun yerine:
"{count} " + t("items") + " " + t("in_cart")
şunu kullanın: tek bir yer tutuculu mesaj — "{count} items in your cart". Çevirmen kelimelerin sırasını güvenle yeniden düzenleyebilir.
RTL yalnızca metin yönü değildir. Düzen akışı tersine döner, bazı simgeler (geri okları gibi) aynalanmalı ve karışık içerik (Arapça + İngilizce ürün kodu) şaşırtıcı bir sırada görüntülenebilir. Gerçek ekranları test edin; sadece tek bir etiketi değil ve UI bileşenlerinin yön değişikliğini desteklediğinden emin olun.
Kullanıcının yazdığını asla çevirmeyin (isimler, adresler, destek ticket'ları, sohbet mesajları). Çevreleyen etiketleri çevirebilir ve çevreleyen meta verileri (tarihler, sayılar) formatlayabilirsiniz, ama içeriğin kendisi olduğu gibi kalmalıdır. Otomatik çeviri ekleyecekseniz, bunu açık bir özellik ve “orijinal/çevrilmiş” geçişi ile yapın.
Pratik bir örnek: Koder.ai ile oluşturulmuş bir uygulama şu şekilde gösterebilir: “{name} renewed on {date} for {amount}”. Bunu tek bir mesaj olarak tutun, {date} ve {amount} locale'e göre formatlayın ve kullanıcının saat diliminde gösterin. Bu tek desen çok fazla çeviri borcunu önler.
Hataları genelde önleyen kısa kurallar:
Çeviri borcu genelde “sadece bir hızlı dize” ile başlar ve sonra haftalar süren temizlik işine dönüşür. Sohbetle oluşturulan projelerde bu daha hızlı olur çünkü UI metni bileşenlerin, formların ve hatta backend mesajlarının içinde üretilir.
En pahalı sorunlar uygulama genelinde yayılan ve bulunması zor olanlardır.
Bir React web uygulaması ve bir Flutter mobil uygulaması faturalar banner'ı olarak “You have 1 free credit left” gösterir. Web metnini biri “You have one credit remaining” diye değiştirir ve anahtarı tam cümle olarak bırakır. Mobil eski anahtarı kullanmaya devam eder. Şimdi bir kavram için iki anahtarınız var ve çevirmenler ikisini de görür.
Daha iyi bir desen stabil anahtarlar (billing.creditsRemaining) ve ICU mesajları ile çoğullaştırmadır ki dil bilgisi her dilde doğru olsun. Eğer Koder.ai gibi bir araç kullanıyorsanız, erken bir kural ekleyin: sohbet içinde üretilen herhangi bir kullanıcıya dönük metin, bileşenlerin veya sunucu hatalarının içine değil, çeviri dosyalarına gitmelidir. Bu küçük alışkanlık, sohbetle oluşturulan uygulamalar için uluslararasılaştırma mimarisini proje büyüdükçe korur.
Uluslararasılaştırma karmaşık geldiğinde genelde temel kurallar yazılmamıştır. Küçük bir kontrol listesi ve somut bir örnek, ekibinizi (ve gelecekteki sizi) çeviri borcundan uzak tutabilir.
Yeni bir ekran için çalıştırabileceğiniz hızlı kontrol listesi:
billing.invoice.paidStatus, billing.greenLabel değil).Basit bir örnek: faturalama ekranı İngilizce, İspanyolca ve Japonca olarak yayınlanacak. UI şunları içeriyor: “Invoice”, “Paid”, “Due in 3 days”, “1 payment method” / “2 payment methods” ve toplam “$1,234.50”. Sohbetle oluşturulan uygulamalar için uluslararasılaştırma mimarisi ile bunu bir kez anahtarlarla tanımlarsınız (web ve mobil paylaşılan), her dil sadece değerleri doldurur. “Due in {days} days” bir ICU mesajı olur ve para formatlaması sabit virgül/virgül kurallarından değil locale'e göre yapılır.
Dilleri özellik özellik yayınlayın, büyük bir yeniden yazım olarak değil:
Yeni özelliklerin tutarlı kalması için iki şeyi belgelendirin: anahtar adlandırma kurallarınız (örneklerle) ve dizelerin “tamamlanmış” tanımı (gömülü sabit metin yok, çoğullar için ICU, tarih/sayı formatlaması, paylaşılan kataloğa ekleme).
Sonraki adımlar: Koder.ai'de inşa ediyorsanız, UI üretmeden önce ekranları ve anahtarları tanımlamak için Planning Mode'u kullanın. Ardından snapshot'lar ve rollback ile kopya ve çeviriler üzerinde güvenli yinelemeler yaparak web ve mobil arasında kırık sürümler riski olmadan ilerleyin.