8 min

Architektura internacjonalizacji dla aplikacji tworzonych w czacie

Architektura internacjonalizacji dla aplikacji tworzonych w czacie: zdefiniuj stabilne klucze tekstowe, reguły pluralizacji i jeden workflow tłumaczeń spójny dla web i mobile.

Architektura internacjonalizacji dla aplikacji tworzonych w czacie

Co psuje się pierwsze, gdy dodasz więcej języków

Pierwsze, co się psuje, to nie kod. To słowa.

Aplikacje tworzone w czacie często zaczynają jako szybki prototyp: wpisujesz „Dodaj przycisk z napisem Zapisz”, interfejs się pojawia i idziesz dalej. Tygodnie później chcesz hiszpański i niemiecki i odkrywasz, że te „tymczasowe” etykiety są rozrzucone po ekranach, komponentach, e‑mailach i komunikatach błędów.

Zmiany treści zdarzają się też częściej niż zmiany kodu. Nazwy produktów się zmieniają, teksty prawne są aktualizowane, onboarding jest przepisywany, a wsparcie prosi o jaśniejsze komunikaty o błędach. Jeśli tekst żyje bezpośrednio w kodzie UI, każda drobna zmiana treści staje się ryzykownym wydaniem, i łatwo pominąć miejsca, gdzie ta sama idea jest sformułowana inaczej.

Oto wczesne symptomy, które sygnalizują, że narastasz dług tłumaczeniowy:

  • Mieszane języki na jednym ekranie (niektóre ciągi przetłumaczone, inne nadal po angielsku).
  • Ten sam label zdublowany z drobnymi różnicami („Sign up”, „Sign Up”, „Create account”).
  • Zepsute układy, gdy tekst się wydłuża (przyciski wystają, nagłówki łamią się nieładnie).
  • Mobile i web rozjeżdżają się (różne słowa dla tej samej akcji).
  • Treści supportu i komunikaty systemowe zostają z tyłu względem UI.

Realistyczny przykład: budujesz prosty CRM w Koder.ai. Aplikacja webowa mówi „Deal stage”, aplikacja mobilna „Pipeline step”, a toast błędu „Invalid status”. Nawet jeśli wszystkie trzy są przetłumaczone, użytkownicy odczują niespójność, bo pojęcia nie pasują do siebie.

„Spójne” nie znaczy „ten sam ciąg znaków wszędzie”. Oznacza to:

  • Ta sama koncepcja używa tego samego klucza i tego samego znaczenia na wszystkich ekranach.
  • Web i mobile dzielą to samo źródło prawdy dla tłumaczeń.
  • Ton i terminologia są stabilne (formalny vs swobodny, „customer” vs „client”).
  • Układy UI są zaprojektowane tak, by obsługiwać krótsze i dłuższe frazy.

Gdy potraktujesz tekst jako dane produktu, a nie dekorację, dodawanie języków przestaje być popłochiem, a staje się rutynową częścią budowy.

Podstawowe pojęcia i prosty cel

Internationalization (i18n) to praca, którą wykonujesz, aby aplikacja mogła obsługiwać wiele języków bez przepisywania kodu. Localization (l10n) to konkretna treść dla danego języka i regionu, np. francuski (Kanada) z odpowiednimi słowami, formatami dat i tonem.

Prosty cel: każdy fragment tekstu widocznego dla użytkownika powinien być wybierany przez stabilny klucz, a nie wpisywany bezpośrednio w kodzie UI. Jeśli możesz zmienić zdanie bez otwierania komponentu React czy widgetu Flutter, jesteś na dobrej drodze. To sedno architektury i18n dla aplikacji tworzonych w czacie, gdzie łatwo przypadkowo wypuścić na stałe tekst wygenerowany podczas sesji czatu.

Tekst widoczny dla użytkownika jest szerszy, niż wiele zespołów myśli. Obejmuje przyciski, etykiety, błędy walidacji, puste stany, wskazówki w onboarding, powiadomienia push, e‑maile, eksporty PDF i każdą wiadomość, którą użytkownik może zobaczyć lub usłyszeć. Zazwyczaj nie obejmuje logów wewnętrznych, nazw kolumn w bazie, identyfikatorów zdarzeń analitycznych, feature flagów ani debugowych komunikatów tylko dla adminów.

Gdzie powinny być przechowywane tłumaczenia? W praktyce często i frontend i backend, z wyraźną granicą odpowiedzialności.

  • Frontend odpowiada za chrome UI: nawigację, formularze, menu i większość tekstu ekranowego.
  • Backend odpowiada za komunikaty, które sam generuje: maile transakcyjne, walidacje po stronie serwera i wszystko zwracane jako odpowiedź błędu.
  • Wspólne domeny (np. etykiety statusu zamówienia) powinny pochodzić z jednego źródła prawdy, żeby web i mobile się nie rozjeżdżały.

Błąd do uniknięcia to mieszanie odpowiedzialności. Jeśli backend zwraca w pełni napisane po angielsku zdania dla błędów UI, frontend nie będzie ich mógł dobrze zlokalizować. Lepszy wzorzec: backend zwraca kod błędu (i ewentualnie bezpieczne parametry), a klient mapuje ten kod na zlokalizowany komunikat.

Własność tekstu to decyzja produktowa, nie szczegół techniczny. Zdecyduj wcześnie, kto może zmieniać słowa i zatwierdzać ton.

Jeśli produkt ma własność kopi, traktuj tłumaczenia jak treść: wersjonuj je, przeglądaj i daj produktowi bezpieczny sposób zgłaszania zmian. Jeśli inżynieria ma własność kopi, ustal regułę: każdy nowy tekst UI musi mieć klucz i domyślne tłumaczenie, zanim trafi do wydania.

Przykład: jeśli w flow rejestracji masz „Create account” w trzech różnych ekranach, zrób z tego jeden klucz używany wszędzie. To utrzymuje spójne znaczenie, przyspiesza tłumaczy i zapobiega temu, że drobne zmiany w słownictwie przeistoczą się w porządkowanie wielu ekranów później.

Jak strukturyzować klucze tekstowe, aby pozostały stabilne

Klucze są kontraktem między twoim UI a tłumaczeniami. Jeśli ten kontrakt ciągle się zmienia, dostaniesz brakujące teksty, szybkie poprawki i niespójne słownictwo między web i mobile. Dobra architektura i18n dla aplikacji tworzonych w czacie zaczyna się od jednej zasady: klucze powinny opisywać znaczenie, a nie aktualne angielskie zdanie.

Używaj stabilnych identyfikatorów jako kluczy (np. billing.invoice.payNow) zamiast pełnej treści (np. "Pay now"). Klucze‑zdania łamią się w momencie, gdy ktoś zmieni słownictwo, doda interpunkcję lub zmieni wielkość liter.

Praktyczny wzorzec, który pozostaje czytelny: ekran (lub domena) + komponent + intencja. Trzymaj się nudnego i przewidywalnego formatu.

Przykłady:

  • auth.login.title
  • auth.login.emailLabel
  • billing.checkout.payButton
  • nav.settings
  • errors.network.offline

Decyduj, kiedy ponownie użyć klucza, a kiedy stworzyć nowy, pytając: „Czy znaczenie jest identyczne w każdym miejscu?” Ponownie używaj kluczy dla naprawdę ogólnych akcji, ale dziel klucze, gdy kontekst się zmienia. Na przykład „Save” w ekranie profilu może być prostą akcją, podczas gdy „Save” w złożonym edytorze może wymagać bardziej specyficznego tonu w niektórych językach.

Trzymaj wspólne teksty UI w dedykowanych przestrzeniach nazw, żeby nie powielać ich na różnych ekranach. Przykładowe koszyki, które dobrze działają:

  • common.actions.* (save, cancel, delete)
  • common.status.* (loading, success)
  • common.fields.* (search, password)
  • errors.* (validation, network)
  • nav.* (tabs, menu items)

Gdy sformułowanie się zmienia, ale znaczenie pozostaje to samo, zachowaj klucz i zaktualizuj jedynie wartości tłumaczeń. O to chodzi w stabilnych identyfikatorach. Jeśli znaczenie się zmienia (nawet subtelnie), stwórz nowy klucz i zostaw stary na miejscu, dopóki nie potwierdzisz, że nikt go nie używa. To zapobiega „cichym” niezgodnościom, gdy stare tłumaczenie formalnie istnieje, ale jest teraz niepoprawne.

Mały przykład w stylu Koder.ai: twój czat generuje aplikację React i aplikację Flutter. Jeśli obie używają common.actions.save, masz spójne tłumaczenia wszędzie. Ale jeśli web używa profile.save, a mobile account.saveButton, z czasem się rozjedziecie, nawet jeśli angielski dziś wygląda identycznie.

Gdzie trzymać ciągi i jak organizować pliki tłumaczeń

Traktuj język źródłowy (często angielski) jako pojedyncze źródło prawdy. Trzymaj go w jednym miejscu, przeglądaj go jak kod i unikaj sytuacji, w której teksty pojawiają się w losowych komponentach „na chwilę”. To najszybszy sposób, by uniknąć na stałe wpisanego tekstu w UI i późniejszego przepisywania.

Prosta zasada: aplikacja może wyświetlać tekst tylko z systemu i18n. Jeśli ktoś potrzebuje nowej treści, dodaje najpierw klucz i domyślny komunikat, a potem używa tego klucza w UI. To utrzymuje architekturę i18n stabilną nawet wtedy, gdy funkcje się przemieszczają.

Układ folderów, który pozostaje rozsądny

Jeśli wysyłasz zarówno web, jak i mobile, chcesz jeden wspólny katalog kluczy oraz miejsce, gdzie zespoły funkcyjne mogą pracować niezależnie. Praktyczny układ:

  • /i18n
  • /i18n/locales/en.json (źródło)
  • /i18n/locales/es.json, /i18n/locales/fr.json, ...
  • /i18n/features/billing.json, /i18n/features/auth.json, ...
  • /i18n/shared.json (przyciski, wspólne etykiety, błędy)

Trzymaj klucze identyczne na wszystkich platformach, nawet jeśli implementacja się różni (React na web, Flutter na mobile). Jeśli używasz platformy jak Koder.ai do generowania obu aplikacji z czatu, eksport kodu jest łatwiejszy, gdy oba projekty wskazują na te same nazwy kluczy i format wiadomości.

Wersjonowanie i review, które zapobiegają dłgowi tłumaczeniowemu

Tłumaczenia zmieniają się w czasie. Traktuj zmiany jak zmiany produktowe: małe, przeglądane i śledzone. Dobre review skupia się na znaczeniu i ponownym użyciu, a nie tylko na ortografii.

  • Wymagaj PR review dla każdej zmiany w locale źródłowym
  • Blokuj usuwanie kluczy bez wyszukiwania i planu
  • Dodawaj notatki dla tłumaczy, gdy tekst jest niejednoznaczny
  • Użyj prostego checku „brakujące tłumaczenia” w CI

Aby powstrzymać dryf kluczy między zespołami, przypisz klucze do funkcji (billing., auth.) i nigdy nie zmieniaj nazw kluczy tylko dlatego, że zmieniło się słownictwo. Aktualizuj komunikat, zachowaj klucz. Klucze są identyfikatorami, nie kopią.

Pluralizacja i gramatyka bez obejść

Wysyłaj web i mobile razem
Generuj aplikacje React (web) i Flutter (mobile), które używają tych samych kluczy tłumaczeń.

Zasady mnogiej formy różnią się między językami, więc prosty angielski schemat (1 vs wszystko inne) szybko zawodzi. Niektóre języki mają osobne formy dla 0, 1, 2–4 i wielu innych. Inne zmieniają całe zdanie, nie tylko rzeczownik. Jeśli wgrasz logikę pluralizacji w UI za pomocą if‑ów, skończysz z duplikowaniem tekstów i pominiętymi przypadkami.

Bezpieczniejsze podejście: trzymaj jedną elastyczną wiadomość na pomysł i pozwól warstwie i18n dobrać właściwą formę. Komunikaty w stylu ICU są do tego stworzone. Przenoszą decyzje gramatyczne do tłumaczenia, a nie do komponentów.

Oto mały przykład, który obejmuje przypadki, o których ludzie zapominają:

itemsCount = "{count, plural, =0 {No items} one {# item} other {# items}}"

Ten pojedynczy klucz obejmuje 0, 1 i wszystko inne. Tłumacze mogą zastąpić go właściwymi formami mnogimi dla swojego języka bez twojej ingerencji.

Gdy potrzebujesz sformułowań zależnych od płci lub roli, unikaj tworzenia oddzielnych kluczy jak welcome_male i welcome_female, chyba że produkt tego naprawdę wymaga. Użyj select, żeby zdanie pozostało jedną całością:

welcomeUser = "{gender, select, female {Welcome, Ms. {name}} male {Welcome, Mr. {name}} other {Welcome, {name}}}"

Aby uniknąć utknięcia w pułapce przypadków gramatycznych, utrzymuj zdania jak najbardziej kompletne. Nie sklejaj fragmentów jak "{count} " + t('items'), ponieważ wiele języków nie pozwala na taką zamianę kolejności wyrazów. Wol preferuj jedną wiadomość, która zawiera liczbę, rzeczownik i otaczające słowa.

Prosta zasada, która dobrze działa w aplikacjach tworzonych w czacie (w tym projektach Koder.ai): jeśli zdanie zawiera liczbę, osobę lub status, zrób z niego komunikat ICU od pierwszego dnia. Kosztuje to trochę więcej na początku, ale oszczędza dużo długu tłumaczeniowego później.

Utrzymywanie spójności tłumaczeń web i mobile

Jeśli twoja aplikacja React i aplikacja Flutter trzymają osobne pliki tłumaczeń, będą się z czasem rozjeżdżać. Ten sam przycisk dostanie inne słowo, klucz będzie miał różne znaczenia na web i mobile, a zgłoszenia do supportu zaczną mówić „aplikacja mówi X, a strona Y”.

Najprostsza naprawa jest też najważniejsza: wybierz jedno źródło prawdy i traktuj je jak kod. Dla większości zespołów oznacza to jedną wspólną serię plików locale (np. JSON z komunikatami w stylu ICU), które konsumują zarówno web, jak i mobile. Gdy budujesz aplikacje przez czat i generatory, to ma dodatkowe znaczenie, bo łatwo przypadkowo stworzyć nowy tekst w dwóch miejscach.

Jedno wspólne źródło prawdy

Praktyczne ustawienie to mały „pakiet i18n” lub folder zawierający:

  • Pliki locale dla każdego języka (te same klucze wszędzie)
  • Zasady formatu wiadomości (ICU dla pluralizacji i placeholderów)
  • Krótkie README wyjaśniające, jak dodawać klucze

React i Flutter stają się wtedy konsumentami. Nie powinny wymyślać nowych kluczy lokalnie. W workflowie w stylu Koder.ai możesz generować oba klienty z tego samego zestawu kluczy i trzymać zmiany pod review jak każdy inny update kodu.

Wyrównanie backendu to część tej samej historii. Błędy, powiadomienia i e‑maile nie powinny być ręcznie pisanymi angielskimi ciągami w Go. Zamiast tego zwracaj stabilne kody błędów (np. auth.invalid_password) plus bezpieczne parametry. Klienci mapują kody na przetłumaczony tekst. Dla maili wysyłanych z serwera serwer może renderować szablony używając tych samych kluczy i plików locale.

Zasady, które utrzymują synchronizację

Stwórz małą księgę reguł i egzekwuj ją w code review:

  • Nowy tekst UI wymaga najpierw klucza w wspólnych plikach locale
  • Klucze muszą zawierać czytelny namespace i intencję (nie pozycję na ekranie)
  • Każdy klucz musi mieć raz zdefiniowane placeholdery i używać ich w ten sam sposób wszędzie
  • Jeśli dwa zdania różnią się znaczeniem, nigdy nie dzielą klucza
  • Jeśli dwa klucze znaczą to samo, usuń jeden i wybierz zwycięzcę

Aby zapobiec duplikatom kluczy o różnych znaczeniach, dodaj pole „description” (lub plik komentarzy) dla tłumaczy i przyszłego siebie. Przykład: billing.trial_days_left powinien wyjaśnić, czy jest pokazywany jako banner, e‑mail, czy w obu miejscach. To jedno zdanie często zatrzymuje „wystarczająco podobne” ponowne użycia, które tworzą dług tłumaczeniowy.

Ta spójność to kręgosłup architektury i18n dla aplikacji tworzonych w czacie: jedno wspólne słownictwo, wiele powierzchni i brak niespodzianek przy wypuszczaniu kolejnego języka.

Krok po kroku — ustawienia, które możesz zastosować w realnym projekcie

Zbuduj wielojęzyczne MVP szybciej
Opisz swój produkt w czacie i przygotuj cały tekst widoczny dla użytkownika do tłumaczenia.

Dobra architektura i18n dla aplikacji tworzonych w czacie zaczyna się prosto: jeden zestaw kluczy wiadomości, jedno źródło prawdy dla kopii i te same zasady na web i mobile. Jeśli budujesz szybko (np. z Koder.ai), ta struktura pozwala zachować tempo bez generowania długu tłumaczeniowego.

Praktyczne ustawienia (web + mobile)

Wybierz locale wcześnie i ustal, co się dzieje, gdy tłumaczenie braknie. Popularny wybór: pokaż preferowany język użytkownika, jeśli dostępny; w przeciwnym razie użyj angielskiego; loguj brakujące klucze, żeby naprawić je przed kolejnym wydaniem.

Następnie wprowadź to w życie:

  • Zdefiniuj locale i fallback: Zdecyduj obsługiwane języki, locale domyślne i jasną kolejność fallbacku. Uzgodnij też, jak wykrywać locale (ustawienia przeglądarki/aplikacji, profil użytkownika).
  • Stwórz funkcję tłumaczącą i konwencję kluczy: Używaj stabilnych, opartych na znaczeniu kluczy (nie pełnych zdań). Na przykład: billing.plan_name.pro lub auth.error.invalid_password. Trzymaj te same klucze wszędzie.
  • Podłącz to do React i Flutter: W React opakuj aplikację providerem i18n i używaj t("key") w komponentach. W Flutter użyj wrappera lokalizacyjnego i wywołuj ten sam lookup oparty na kluczu w widgetach. Cel to te same klucze, nie ta sama biblioteka.
  • Wspieraj zmienne i reguły pluralizacji od pierwszego dnia: Używaj komunikatów w stylu ICU dla pluralizacji i placeholderów, np. {count, plural, one {# file} other {# files}} i Hello, {name}. To unika obejść typu if (count === 1) rozrzuconych po ekranach.
  • Dodaj lekki krok review kopii: Przed wypuszczeniem przeglądaj nowe lub zmienione ciągi: sprawdź nazewnictwo kluczy, usuń wpisane na stałe teksty w UI, potwierdź zgodność placeholderów i upewnij się, że web i mobile załapały zmianę.

Na koniec przetestuj jeden język z dłuższymi słowami (niemiecki) i jeden z inną interpunkcją. To szybko ujawni przyciski, które wystają, nagłówki, które źle się łamią, i układy zakładające długość angielskich słów.

Jeśli trzymasz tłumaczenia we wspólnym folderze (lub generowanym pakiecie) i traktujesz zmiany kopii jak zmiany w kodzie, twoje aplikacje web i mobile pozostaną spójne, nawet gdy funkcje powstają szybko w czacie.

Treści dynamiczne: daty, liczby i tekst od użytkowników

Przetłumaczone ciągi UI to tylko połowa problemu. Większość aplikacji pokazuje też zmienne wartości jak daty, ceny, liczniki i nazwy. Jeśli potraktujesz te wartości jako zwykły tekst, dostaniesz dziwne formaty, złe strefy czasowe i zdania, które brzmią „nie tak” w wielu językach.

Zacznij od formatowania liczb, waluty i dat zgodnie z regułami locale, a nie własnym kodem. Użytkownik we Francji spodziewa się „1 234,50 €”, a w USA „$1,234.50”. To samo dotyczy dat: „03/04/2026” jest niejednoznaczne, ale formatowanie locale usuwa wątpliwości.

Strefy czasowe to kolejna pułapka. Serwery powinny przechowywać znaczki czasu w neutralnej formie (zwykle UTC), ale użytkownicy oczekują widoku w swojej strefie. Na przykład: zamówienie utworzone o 23:30 UTC może być „jutro” dla osoby w Tokio. Ustal jedną zasadę na ekran: pokazuj czas lokalny użytkownika dla wydarzeń osobistych, a stałą strefę biznesową dla np. okien odbioru w sklepie (i oznacz to wyraźnie).

Unikaj budowania zdań przez łączenie przetłumaczonych fragmentów. To łamie gramatykę, bo kolejność słów zmienia się między językami. Zamiast:

"{count} " + t("items") + " " + t("in_cart")

użyj jednej wiadomości z placeholderami, np. "{count} items in your cart". Tłumacz może wtedy bezpiecznie zmienić kolejność słów.

Języki pisane od prawej do lewej (RTL)

RTL to nie tylko kierunek tekstu. Przepływ układu się odwraca, niektóre ikony trzeba zmirrorować (np. strzałki wstecz), a mieszana zawartość (arabski + angielski kod produktu) może renderować w zaskakującej kolejności. Testuj realne ekrany, nie tylko pojedyncze etykiety, i upewnij się, że komponenty UI wspierają zmianę kierunku.

Treści tworzone przez użytkowników

Nigdy nie tłumacz tego, co napisał użytkownik (imiona, adresy, zgłoszenia do supportu, wiadomości czatu). Możesz przetłumaczyć etykiety wokół nich i sformatować metadane (daty, liczby), ale sama treść musi pozostać bez zmian. Jeśli dodasz autotranslację później, niech to będzie jawna funkcja z przełącznikiem „oryginał/przekład”.

Praktyczny przykład: aplikacja zbudowana w Koder.ai może pokazywać „{name} renewed on {date} for {amount}”. Trzymaj to jako jedną wiadomość, formatuj {date} i {amount} według locale i wyświetlaj w strefie czasowej użytkownika. Ten wzorzec zapobiega wielu problemom z tłumaczeniami.

Szybkie reguły, które zwykle zapobiegają błędom:

  • Przechowuj znaczniki czasu w UTC, formatuj dla locale i strefy czasowej widza.
  • Używaj placeholderów w pełnych zdaniach, nigdy nie sklejaj fragmentów.
  • Formatuj walutę zgodnie z regułami locale i używaj poprawnego kodu waluty.
  • Przetestuj przynajmniej jedną lokalizację RTL na realnych ekranach.
  • Nie tłumacz domyślnie treści użytkowników.

Typowe błędy, które tworzą dług tłumaczeniowy

Lokalizuj błędy API poprawnie
Twórz backendy w Go, które zwracają kody błędów, które klienci mogą lokalizować spójnie.

Dług tłumaczeniowy zwykle zaczyna się od „jeszcze jednego szybkiego stringa” i przeradza w tygodnie sprzątania. W projektach tworzonych w czacie może się to stać jeszcze szybciej, bo teksty UI są generowane wewnątrz komponentów, formularzy, a nawet komunikatów backendu.

Problemy, które najbardziej bolą później

Najdroższe do naprawy są problemy, które rozprzestrzeniają się po aplikacji i trudno je odnaleźć.

  • Twarde wpisywanie kopii wewnątrz komponentów UI, w tym placeholderów, pustych stanów i etykiet przycisków. Nie możesz tego zrewidować ani ponownie użyć, a drobne zmiany wymagają edycji kodu.
  • Pozwalanie backendowi na zwracanie angielskich zdań walidacyjnych i błędów API. UI zaczyna pokazywać mieszane języki i nie da się wiarygodnie mapować błędów na przetłumaczone komunikaty.
  • Używanie pełnego angielskiego zdania jako klucza tłumaczenia. Wydaje się wygodne, dopóki kopia się nie zmieni — wtedy klucze churnują, stare klucze zostają i tracisz pamięć tłumaczeń.
  • Kopiowanie kluczy między web i mobile i edytowanie ich oddzielnie. Z czasem „te same” ekrany się rozjeżdżają i użytkownicy zauważają niespójności.
  • Odkładanie reguł pluralizacji do momentu dodania pierwszego nie‑angielskiego języka. Wtedy znajdziesz dziesiątki błędów „1 items” i niezgrabnej gramatyki, których nie rozwiążesz prostymi if‑ami.

Krótki przykład (jak to wygląda w praktyce)

Wyobraź sobie aplikację React i Flutter, które pokazują banner rozliczeniowy: „You have 1 free credit left”. Ktoś zmienia tekst na web na „You have one credit remaining” i zostawia klucz jako całe zdanie. Mobile nadal używa starego klucza. Teraz masz dwa klucze dla jednej koncepcji i tłumacze widzą oba.

Lepszy wzorzec to stabilne klucze (np. billing.creditsRemaining) i pluralizacja w stylu ICU, żeby gramatyka była poprawna we wszystkich językach. Jeśli używasz narzędzia generującego UI jak Koder.ai, dodaj wczesną regułę: każdy tekst widoczny dla użytkownika wygenerowany w czacie powinien trafić do plików tłumaczeń, a nie do komponentów czy błędów serwera. Ten mały nawyk chroni twoją architekturę i18n, gdy projekt rośnie.

Szybka lista kontrolna, realistyczny przykład i kolejne kroki

Gdy internacjonalizacja wydaje się chaotyczna, zwykle dlatego, że podstawowe zasady nie zostały spisane. Mała lista kontrolna i jeden konkretny przykład mogą utrzymać zespół (i przyszłego siebie) z daleka od długu tłumaczeniowego.

Oto szybka lista kontrolna na każdy nowy ekran:

  • Stabilne klucze: jeden klucz na znaczenie, nie na brzmienie (przykład: billing.invoice.paidStatus, nie billing.greenLabel).
  • Fallbacky: zdefiniuj język domyślny i decyzję co robić, gdy klucz braknie (pokaż fallback, zaloguj, zablokuj wydanie).
  • Reguły mnogie: używaj komunikatów ICU dla liczników zamiast hacków tekstowych.
  • Formatowanie: formatuj daty, pieniądze i liczby według locale (trzymaj walutę oddzielnie od języka).
  • Sprawdzenie RTL: przetestuj przynajmniej jeden język RTL wcześnie, żeby problemy z układem ujawniły się, zanim masz 200 ekranów.

Prosty przykład: wprowadzasz ekran rozliczeń w angielskim, hiszpańskim i japońskim. UI ma: „Invoice”, „Paid”, „Due in 3 days”, „1 payment method” / „2 payment methods” oraz sumę typu „$1,234.50”. Jeśli zbudujesz to zgodnie z architekturą i18n dla aplikacji tworzonych w czacie, zdefiniujesz klucze raz (wspólne dla web i mobile), i każdy język wypełni tylko wartości. „Due in {days} days” stanie się komunikatem ICU, a formatowanie pieniędzy pochodzi z formattera zależnego od locale, nie z twardych przecinków.

Wdrażaj obsługę języków funkcja po funkcji, a nie jako wielki refaktor:

  1. Zacznij od jednego flow o dużym ruchu (billing, onboarding lub checkout).
  2. Przenieś twardo wpisany tekst UI do plików tłumaczeń i zastąp kluczami.
  3. Dodaj komunikaty mnogie i formatowanie dla tego samego flow.
  4. Przejdź do następnej funkcji dopiero, gdy liczba brakujących kluczy będzie bliska zeru.

Udokumentuj dwie rzeczy, żeby nowe funkcje pozostały spójne: reguły nazewnictwa kluczy (z przykładami) i „definition of done” dla tekstów (brak twardo wpisanego copy, ICU dla pluralizacji, formatowanie dat/liczb, dodane do wspólnych katalogów).

Kolejne kroki: jeśli budujesz w Koder.ai, użyj Planning Mode, aby zdefiniować ekrany i klucze przed wygenerowaniem UI. Potem używaj snapshotów i rollbacków, by bezpiecznie iterować nad kopiami i tłumaczeniami między web i mobile, bez ryzyka zepsutego wydania.

Często zadawane pytania

Jak nazywać klucze tłumaczeń?

Używaj stabilnych kluczy opartych na znaczeniu, takich jak billing.invoice.payNow, zamiast samego angielskiego zdania. Dzięki temu możesz zmieniać brzmienie bez zmiany odwołań w kodzie ani tworzenia zduplikowanych tłumaczeń.

Jakie teksty powinny trafić do plików tłumaczeń?

W systemie tłumaczeń umieszczaj każdy tekst widoczny dla użytkownika, w tym błędy, puste stany, e-maile, powiadomienia i wskazówki podczas wdrażania. Wewnętrzne logi, identyfikatory analityczne i pola bazy danych zwykle nie wymagają tłumaczenia.

Jak zachować spójne brzmienie w wersji webowej i mobilnej?

Używaj jednego wspólnego katalogu kluczy i komunikatów dla poszczególnych ustawień regionalnych w obu klientach. React i Flutter mogą korzystać z różnych bibliotek, ale powinny odwoływać się do tych samych nazw kluczy i zasad dotyczących komunikatów.

Czy backend powinien zwracać przetłumaczone komunikaty błędów?

Niech backend zwraca stabilny kod błędu wraz z bezpiecznymi wartościami, a klient wyświetla zlokalizowany komunikat. Na przykład zwracaj auth.invalid_password zamiast angielskiego zdania.

Jak obsługiwać liczbę mnogą w różnych językach?

Używaj komunikatów liczby mnogiej w stylu ICU, aby każdy język mógł stosować własne reguły gramatyczne. Umieszczaj całe zdanie w jednym komunikacie, zamiast dodawać liczbę do osobno przetłumaczonego rzeczownika.

Gdzie powinny znajdować się pliki tłumaczeń?

Trzymaj język źródłowy, często angielski, jako źródło prawdy i przeglądaj zmiany razem z kodem. Grupuj komunikaty według funkcji, a wspólne przestrzenie nazw zachowaj dla typowych działań, pól, nawigacji i błędów.

Czy przy każdej zmianie tekstu potrzebuję nowego klucza?

Zachowaj istniejący klucz, jeśli znaczenie pozostaje takie samo, nawet gdy zmienia się brzmienie. Nowy klucz twórz tylko wtedy, gdy zmienia się znaczenie lub kontekst, a potem usuń stary po potwierdzeniu, że nic z niego nie korzysta.

Jak lokalizować daty, pieniądze i strefy czasowe?

Przechowuj znaczniki czasu w UTC, a następnie formatuj daty, godziny, liczby i waluty zgodnie z ustawieniami regionalnymi oraz strefą czasową odbiorcy. Używaj formatowania zależnego od ustawień regionalnych zamiast na stałe wpisanych przecinków, symboli walut czy wzorców dat.

Co należy testować w językach pisanych od prawej do lewej?

Projektuj całe ekrany w ustawieniach regionalnych RTL, a nie tylko etykiety. W razie potrzeby odwracaj kierunek układu, odbijaj ikony kierunkowe, takie jak strzałki wstecz, i testuj mieszany tekst arabski i łaciński, na przykład kody produktów.

Jaki jest najprostszy sposób na dodanie i18n do istniejącej aplikacji?

Zacznij od jednego intensywnie używanego procesu, takiego jak wdrażanie, rozliczenia lub finalizacja zakupu. Przenieś jego teksty wpisane na stałe do wspólnych komunikatów, dodaj obsługę liczby mnogiej i formatowania, przetestuj dłuższe tłumaczenia, a potem powtórz to dla kolejnej funkcji.

Related posts