10 najczęstszych błędów i18n i jak ich unikasz
Poznaj najczęstsze błędy i18n popełniane przez deweloperów i jak je naprawić. Popraw jakość lokalizacji swojej aplikacji dzięki tym najlepszym praktykom.
Internacjonalizacja (i18n) wydaje się bezproblemowa — dopóki nie odkryjesz, że Twoi niemieccy użytkownicy widzą przycięte przyciski, Twoi japońscy użytkownicy otrzymują urwane fragmenty zdań, a Twoi arabscy użytkownicy mają kompletnie zepsute układy. To nie są przypadki marginalne. To przewidywalne konsekwencje częstych błędów, które większość zespołów deweloperskich popełnia przy pierwszym podejściu do lokalizacji. W tym przewodniku omówimy 10 najczęstszych błędów i18n, dokładnie wyjaśnimy, dlaczego występują i krok po kroku pokażemy, jak naprawić każdy z nich. Niezależnie od tego, czy budujesz nową aplikację, czy ulepszasz istniejącą — unikanie tych pułapek zaoszczędzi ci tygodnie debugowania i zapewni użytkownikom na całym świecie dopracowane doświadczenie.
Błąd nr 1: Hardkodowane ciągi znaków
Twardo zakodowane ciągi znaków to najbardziej podstawowy błąd i18n. Dzieje się tak, ponieważ programiści najpierw koncentrują się na uruchomieniu funkcji i planują 'posprzątać później'. Ale później nigdy nie nadchodzi, i nagle masz tysiące ciągów rozproszonych po setkach plików.
['Zainstaluj framework i18n zanim napiszesz pierwszy element UI', 'Użyj wtyczki Lintera, aby wykrywać twardo zakodowane ciągi w szablonach i komponentach', 'Trzymaj klucze tłumaczeń opisowe i zorganizuj je według funkcji lub strony']
Skonfiguruj swój framework i18n, zanim napiszesz pierwszy wiersz kodu UI.
Użyj wtyczki lintera, aby wykrywać hardkodowane ciągi znaków w szablonach i komponentach.
Trzymaj klucze tłumaczeń opisowe i zorganizowane według funkcji lub strony.
Typowy scenariusz
Programista zapisuje etykietę przycisku bezpośrednio w JSX: <button>Submit Order</button>.
Aplikacja jest udostępniana po angielsku i działa poprawnie. Sześć miesięcy później firma rozwija działalność na Niemcy.
Zespół lokalizacyjny odkrywa ponad 2000 hardkodowanych strings. Modernizacja zajmuje 3 tygodnie i powoduje 47 błędów.
Dlaczego to jest problem
W dojrzałej bazie kodu mogą występować tysiące hardkodowanych łańcuchów znaków. Ich późniejsze wyodrębnienie wymagałoby dotknięcia każdego pliku, ponownego przetestowania każdej komponenty i ryzyka regresji w całym projekcie.
Twardo zakodane ciągi znaków są bezpośrednio osadzone w kodzie źródłowym, szablonach lub komponentach. Nie można ich wyodrębnić, przetłumaczyć ani wymienić podczas uruchomienia bez zmiany samego kodu.
Użytkownicy w lokalizacjach nieangielskich widzą nieprzetłumaczone elementy UI mieszane z przetłumaczoną treścią — chaotyczne i nieprofesjonalne wrażenie.
Jak to naprawić
Przenieś wszystkie ciągi widoczne dla użytkownika od samego początku do plików zasobów.
Skonfiguruj framework tłumaczeń (np. next-intl, react-i18next, vue-i18n) zanim napiszesz swój pierwszy komponent.
Utwórz strukturę plików zasobów (np. messages/de.json) i odwołuj się do wszystkich ciągów za pomocą kluczy tłumaczeń, takich jak t('checkout.submitButton').
Dodaj regułę lintu lub hook pre-commit, który wykrywa surowe literały łańcuchów w komponentach UI.
Błąd nr 10: Tłumaczenie wszystkiego dosłownie.
Nie wszystkie treści powinny być przetłumaczone. Nazwy marek, nazwy podmiotów prawnych, terminy techniczne i niektóre nazwy produktów powinny pozostać w swoim oryginalnym języku. Nadmierne tłumaczenie może powodować problemy prawne, niespójność marek i dezorientację użytkowników.
["Utwórz glosariusz 'Nie tłumaczyć' i udostępnij go wszystkim tłumaczom", "Używaj zablokowanych segmentów lub osobnych namespaces dla marek i terminów prawnych", "Zawsze dostarczaj notatki kontekstowe dla dwuznacznych ciągów znaków, aby zapobiec błędnym tłumaczeniom"]
Utrzymuj glosariusz typu 'nie tłumaczyć' i udostępniaj go wszystkim tłumaczom.
Używaj zablokowanych segmentów lub oddzielnych przestrzeni nazw dla terminów marek i terminów prawnych.
Zawsze podawaj notatki kontekstowe dla dwuznacznych ciągów znaków, aby zapobiec błędnym tłumaczeniom.
Typowy scenariusz
Plik tłumaczeń zawiera nazwę firmy 'CloudForge Inc.' i techniczny termin 'OAuth 2.0 Token' jako zwykłe łańcuchy do przetłumaczenia.
Tłumacz hiszpański przetłumaczy 'CloudForge' na 'ForjaNube' i 'OAuth 2.0 Token' na 'Token OAuth 2.0'.
Wynik: Użytkownicy nie znajdują firmy pod jej prawdziwą nazwą, a deweloperzy czytający hiszpańską dokumentację są zdezorientowani przez nieznane terminy branżowe.
Dlaczego to jest problem
Pojedyncze błędnie przetłumaczone nazwy marek w dokumentach prawnych mogą unieważnić umowę. Naprawa nadmiernego tłumaczenia wymaga przeglądu każdego łańcucha w każdym języku — kilka tygodni pracy.
Jeśli wszystkie ciągi znaków wysyłane są do tłumaczenia bez kontekstu, tłumacze mogą przetłumaczyć nazwy marek ('Apple' → 'Apfel'), terminy prawne ('GmbH' → 'LLC') lub techniczne terminy, które muszą pozostać po angielsku.
Użytkownicy nie znajdują produktów pod ich znanym znakiem towarowym, dokumenty prawne odnoszą się do niewłaściwej spółki, a dokumentacja techniczna staje się niezrozumiała, jeśli takie pojęcia jak 'API Endpoint' są tłumaczone.
Tak to naprawisz
Zaznacz na jasno treści niepodlegające tłumaczeniu i podaj tłumaczom notatki kontekstowe.
Utwórz glosariusz 'Nie tłumaczyć', który wymieni wszystkie nazwy marek, nazwy produktów, podmioty prawne i terminy fachowe, które muszą pozostać niezmienione.
Użyj osobnego namespace'u lub specjalnych kluczy dla treści niepodlegających tłumaczeniu. Wiele narzędzi i18n obsługuje 'zablokowane' segmenty, które tłumacze nie mogą edytować.
Dodaj komentarze/opisy tłumaczy do plików tłumaczeń, które wyjaśniają kontekst: 'To jest nazwa marki — nie tłumaczyć' lub 'Termin fachowy — pozostawić po angielsku'.
Błąd nr 2: Łączenie łańcuchów znaków
Zlepianie zdań z fragmentów brzmi logicznie po angielsku, ale nie działa w innych językach. Szyk wyrazów, gramatyka i składnia różnią się znacznie między językami, co czyni łączone ciągi nieprzetłumaczalnymi.
['Nigdy nie łącz zdań przez konkatenację tłumaczonych fragmentów', 'Używaj nazwanych zastępnika ('{name}') zamiast pozycyjnych ({0}) dla jasności', 'Dostarczaj komentarze kontekstowe dla tłumaczy wyjaśniające, co zawiera każdy zastępnik']
Nigdy nie twórz zdań, łącząc fragmenty przetłumaczone.
Używaj nazwanych zastępnika ('{name}') zamiast pozycyjnych ({0}) dla jasności
Dostarcz komentarze kontekstowe dla tłumaczy, wyjaśniające, co zawiera każdy znacznik zastępczy.
Typowy scenariusz
Programista pisze: 'You have ' + count + ' items in your ' + cartType + ' cart' — działa perfekcyjnie po angielsku.
Tłumacz niemiecki otrzymuje trzy oddzielne fragmenty i nie może utworzyć gramatycznie poprawnego zdania, ponieważ szyk wyrazów musi zostać zmieniony.
Wynik: Niemieccy użytkownicy widzą 'Sie haben 5 Artikel in Ihrem Warenkorb Standard' — brzmi to sztywno i nieprofesjonalnie.
Dlaczego to jest problem
Każdy zsynchronizowany łańcuch znaków to tykająca bomba czasowa. Przy 20 językach i 50 zsynchronizowanych łańcuchach masz 1 000 potencjalnych błędów gramatycznych, które trzeba naprawić ręcznie.
Łączenie ciągów znaków jak 'Willkommen ' + userName + ', masz ' + count + ' nowych wiadomości' wymaga określonego szyku wyrazów. Tłumacze otrzymują fragmenty bez kontekstu, których nie mogą przestawić.
Użytkownicy widzą zdania z błędną gramatyką. Po niemiecku czasownik często stoi na końcu. W arabskim cała struktura jest odwrócona. Efekt brzmi jak nonsens.
Jak to naprawisz?
Użyj komunikatów parametryzowanych z nazwanymi placeholderami, aby tłumacze mogli przestawić całe zdanie.
Zastąp konkatenację jednym kluczem wiadomości z zastępnikiem: 'cart.summary': 'Masz {count} przedmiotów w swoim '{cartType}'-koszyku'.
Przekaż zmienne jako parametry do funkcji tłumaczącej: t('cart.summary', { count: 5, cartType: 'Premium' }).
Tłumacze mogą teraz swobodnie zmieniać kolejność: 'W Twoim '{cartType}'-koszyku znajduje się {count} przedmiotów' — poprawna gramatycznie niemiecka wersja.
Błąd nr 3: Ignorowanie liczby mnogiej
Angielski ma dwa rodzaje liczby mnogiej: liczby pojedynczej i mnogiej. Deweloperzy często zakładają, że wszystkie języki działają tak samo. Tak nie jest. Polski ma cztery formy, arabski ma sześć, a nawet języki takie jak francuski traktują zero inaczej niż angielski.
['Zawsze używaj ICU MessageFormat lub równoważnej biblioteki do treści policzalnych', 'Nigdy nie pisz własnej logiki liczby mnogiej — polegaj na regułach CLDR', 'Testuj liczbę mnogą z wartościami takich jak 0, 1, 2, 5, 21 i 100, aby objąć wszystkie kategorie']
Zawsze używaj ICU MessageFormat lub odpowiadającej biblioteki do treści zliczalnych.
Nigdy nie pisz własnej logiki liczby mnogiej — zaufaj regułom CLDR.
Przetestuj formy liczby mnogiej dla wartości takich jak 0, 1, 2, 5, 21 i 100, aby objąć wszystkie kategorie.
Typowy scenariusz
Programista pisze: count + (count === 1 ? ' Datei' : ' Dateien') — traktuje niemiecki poprawnie.
Polski tłumacz potrzebuje 4 form: 1 plik, 2–4 pliki, 5–21 plików, 22–24 pliki. Prosty ternary nie potrafi tego wyrazić.
Wynik: Polscy użytkownicy widzą '5 pliki' (błędna forma) zamiast '5 plików' (poprawna forma), a aplikacja wygląda na zepsutą.
Dlaczego to problem
Każdy rzeczownik policzalny w twojej aplikacji wymaga obsługi liczby mnogiej. Przy 50 takich łańcuchach znaków i 20 językach to 1 000 reguł liczby mnogiej — niemożliwe do ręcznego zarządzania.
Proste warunki if/else (count === 1 ? 'Datei' : 'Dateien') obsługują tylko niemiecki/angielski. CLDR definiuje do 6 kategorii liczby mnogiej: zero, one, two, few, many i other. Każdy język wykorzystuje inny podzbiór.
Użytkownicy widzą teksty gramatycznie błędne, takie jak '1 Nachrichten' lub całkowicie błędne formy liczby mnogiej. W kontekstach formalnych to niszczy wiarygodność.
Jak to naprawisz?
Użyj ICU MessageFormat, które obsługuje wszystkie reguły liczby mnogiej CLDR od ręki.
Zdefiniuj komunikaty za pomocą składni ICU: 'fileCount': '{count, plural, one {# Datei} other {# Dateien}}'.
Tłumacz zapewnia wszystkie potrzebne formy liczby mnogiej dla swojego języka. Polski: '{count, plural, one {# plik} few {# pliki} many {# plików} other {# pliku}}'.
Twoja biblioteka i18n automatycznie wybiera prawidłową formę podczas wykonywania, w oparciu o zasady CLDR dla aktywnej lokalizacji.
Błąd nr 4: Stałe szerokości elementów UI
Projektanci tworzą układy o pikselowej precyzji w języku angielskim, a deweloperzy implementują je z ustalonymi szerokościami. Jednak przetłumaczony tekst może być drastycznie dłuższy lub krótszy. Tekst niemiecki jest około 30% dłuższy niż angielski, podczas gdy tekst chiński może być o 50% krótszy.
['Nigdy nie używaj stałych szerokości w pikselach na elementach z tekstem do tłumaczenia', 'Zaprojektuj 40% rozszerzenie tekstu jako bazową linię — niektóre języki rozwijają się jeszcze bardziej', 'Używaj CSS Flexbox lub Grid dla układów, które dostosowują się do różnych długości treści']
Nigdy nie używaj stałych szerokości pikselowych w elementach z tekstem do przetłumaczenia.
Użyj 40% rozszerzenia tekstu jako podstawy — niektóre języki będą się jeszcze bardziej rozwijać.
Używaj CSS Flexbox lub Grid do układów dopasowujących się do różnej długości treści.
Typowy scenariusz
Projektant tworzy pasek nawigacyjny z 5 przyciskami, każdy dokładnie szerokości 100px — wygląda świetnie po angielsku.
Tłumaczenie niemieckie: 'Settings' staje się 'Einstellungen' (13 vs 8 znaków), 'Submit' staje się 'Absenden' (8 vs 6). Nawigacja przekracza szerokość ekranu.
Wynik: na urządzeniach mobilnych przyciski układają się jeden na drugim lub tekst jest obcięty, co czyni nawigację dla niemieckich użytkowników nieużyteczną.
Dlaczego to jest problem?
Każdy element o stałej szerokości jest potencjalnym punktem awarii. Typowa aplikacja ma setki przycisków, etykiet i kart, które muszą wytrzymać wydłużanie treści.
Kontener o stałej szerokości (width: 120px) i przyciski o stałej wielkości ucina się lub wykracza poza obszar, gdy tekst się wydłuża. CSS overflow: hidden ukrywa zawartość po cichu, podczas gdy overflow: visible psuje układ.
Użytkownicy widzą obcięte etykiety, takie jak 'Einstellu...' zamiast 'Ustawienia', lub przyciski nachodzące na sąsiednie elementy. Krytyczne akcje stają się nieczytelne lub nieklikalne.
Tak to naprawisz
Projektuj i wdrażaj elastyczne układy, które dostosowują się do długości treści we wszystkich lokalizacjach.
Zamień stałe szerokości na min-width, max-width i układy Flex. Używaj CSS Grid lub Flexbox, aby dynamicznie rozdzielać miejsce.
Ustaw kontener tekstu na łamanie wierszy: użyj overflow-wrap: break-word i unikaj white-space: nowrap przy treści do przetłumaczenia.
Przetestuj interfejs użytkownika za pomocą pseudo-lokalizacji, która wydłuża wszystkie ciągi o 40%, aby zasymulować najgorszy scenariusz — jeszcze zanim wyślesz teksty do tłumaczy.
Błąd nr 5: Formatowanie dat i liczb
Dane i liczby wydają się uniwersalne. Jednak 01/02/2025 oznacza 2 stycznia w USA i 1 lutego w Europie. Przecinki i kropki mają inne znaczenie w liczbach: 1,000.50 (USA) vs 1.000,50 (Niemcy). Popełnienie tego błędu prowadzi do zamieszania, błędów danych i utraty zaufania.
['Nigdy nie formatuj danych ani liczb ręcznie za pomocą szablonów łańcuchowych — zawsze używaj interfejsów API Intl', 'Przechowuj wszystkie dane wewnętrznie w formacie ISO 8601 i waluty w najmniejszej jednostce (cent)', 'Przetestuj locale używające różnych separatorów dziesiętnych, układów dat i systemów kalendarzowych']
Nigdy nie formatuj danych ani liczb ręcznie za pomocą szablonów łańcuchów — zawsze używaj interfejsów API Intl.
Zapisuj wszystkie dane w ISO 8601 i wartości walut wewnętrznie w najdrobniejszych jednostkach (centy).
Testuj locale, które używają różnych separatorów dziesiętnych, kolejności dat i systemów kalendarza.
Typowy scenariusz
Programista formatuje datę jako MM/DD/YYYY i cenę jako $1,234.50 — poprawne dla użytkowników z USA.
Niemiecki użytkownik widzi datę 03/04/2025 i odczytuje ją jako 3 kwietnia (konwencja DD/MM/RRRR). Cena $1,234.50 wydaje się powinna być 1.234,50.
Wynik: Użytkownik rezerwuje lot na niewłaściwą datę i kwestionuje format cen. Zgłoszenia do obsługi klienta rosną w niemieckim rynku o 15%.
Dlaczego to jest problem?
Formatowanie dat i liczb dotyczy każdego wyświetlania danych w twojej aplikacji: tabele, wykresy, formularze, faktury, raporty. Globalne poprawki obejmują setki instancji.
Hardkodowane łańcuchy formatowania, takie jak toLocaleDateString('en-US') lub ręczne formatowanie za pomocą template literals, ignorują faktyczną lokalizację użytkownika. Nawet jeśli locale jest prawidłowe, lecz zły system kalendarza (Gregorian vs Hijri) powoduje problemy.
Użytkownicy odczytują dane błędnie i wprowadzają dane w niewłaściwym formacie. Europejski użytkownik widzący 03/04/2025 może to zinterpretować jako 3 kwietnia zamiast 4 marca — przegapione terminy lub błędne rezerwacje.
Oto jak to naprawić
Użyj wbudowanego API Intl lub biblioteki formatującej uwzględniającej lokalizację dla wszystkich dat, godzin, liczb i walut.
Zastąp ręczne formatowanie przez Intl.DateTimeFormat(locale) dla dat i Intl.NumberFormat(locale, { style: 'currency', currency }) dla cen.
Przechowuj dane wewnętrznie w formacie ISO 8601 (YYYY-MM-DD) i formatuj je tylko do wyświetlania zgodnie z lokalizacją użytkownika.
Przetestuj locale używające różnych separatorów dziesiętnych, układów dat i systemów kalendarzowych.
Błąd nr 6: zapomniano o językach RTL
Języki RTL (right-to-left) takie jak arabski, hebrajski i perski są używane przez ponad 500 milionów ludzi. Mimo to większość aplikacji projektowana jest wyłącznie pod układ od prawej do lewej (RTL). Wsparcie RTL oznacza nie tylko odwracanie tekstu — całe UI musi być lustrzany.
['Używaj od pierwszego dnia wyłącznie logicznych właściwości CSS (inline-start/end, block-start/end)', 'Przetestuj swoją aplikację z dir='rtl' na elemencie HTML przy każdym przeglądzie sprintu', 'Stwórz listę kontrolną testów RTL dla nawigacji, ikon, formularzy i wskaźników postępu']
Używaj od pierwszego dnia wyłącznie logicznych właściwości CSS (inline-start/end, block-start/end).
Przetestuj swoją aplikację z dir='rtl' na elemencie HTML podczas każdego przeglądu sprintu.
Utwórz listę kontrolną RTL do nawigacji, ikon, formularzy i wskaźników postępu.
Typowy scenariusz
Programiści używają margin-left: 16px i text-align: left w całej aplikacji — typowa praktyka LTR.
Aplikacja uruchomiona w Arabii Saudyjskiej. Strzałki wstecz wskazują do przodu, panele boczne pojawiają się po złej stronie, a dane liczbowe nie są prawidłowo wyrównane.
Wynik: Arabscy użytkownicy opuszczają aplikację po 30 sekundach. Zespół potrzebuje 4 tygodni awaryjnego przepisywania CSS, aby naprawić problem.
Dlaczego to jest problem?
Obsługa RTL dotyczy każdego pojedynczego elementu Twojej aplikacji. Wprowadzenie RTL w późniejszym czasie zwykle wymaga przepisywania 30-50% wszystkich reguł CSS i sprawdzenia każdej ikony i układu.
Właściwości CSS takie jak margin-left, padding-right, text-align: left i float: left zakodowują kierunek. Ikony z oznaczeniem kierunku (strzałki, wskaźniki postępu) pokazują w złym kierunku. Nawet wartości border-radius muszą być lustrzane.
Arabscy użytkownicy widzą nawigację w niewłaściwym rogu, pasek postępu idzie do tyłu, a tekst koliduje z interfejsem użytkownika. Aplikacja jest obco i nieprzyjazna w użyciu.
Oto jak to naprawić
Użyj logicznych właściwości CSS i przetestuj od początku układ RTL.
Zastąp wszystkie fizyczne właściwości CSS logicznymi odpowiednikami: margin-left → margin-inline-start, padding-right → padding-inline-end, text-align: left → text-align: start.
Ustaw atrybut dir na elemencie korzenia HTML w zależności od aktywnego locale. Użyj pseudosklasy CSS :dir(rtl) dla RTL-specyficznych nadpisów.
Sprawdź wszystkie ikony pod kątem kierunku. Zamień ikony zależne od kierunku na ich lustrzane wersje lub użyj CSS transform: scaleX(-1) w kontekstach RTL.
Błąd nr 7: Obrazy z tekstem
Wstawianie tekstu w obrazach — czy to w hero-bannerach, przyciskach, infografikach czy zrzutach ekranów — to koszmar lokalizacji. Każde zdjęcie z tekstem musi zostać ponownie stworzone dla każdego języka, co zwiększa koszty projektowe i opóźnia wydania.
['Nigdy nie umieszczaj tekstu możliwego do przetłumaczenia bezpośrednio w obrazach rastrowych (PNG, JPG)', 'Użyj nakładek tekstowych CSS na obrazach tła dla banerów hero i CTA', 'Zautomatyzuj generowanie zrzutów ekranu dla wpisów App Store i stron marketingowych']
Nigdy nie umieszczaj tekstu, który można przetłumaczyć, bezpośrednio w obrazach rastrowych (PNG, JPG).
Używaj nakładek tekstowych CSS na tła obrazów dla bannerów hero i CTA.
Zautomatyzuj generowanie zrzutów ekranu dla listingów App Store i stron marketingowych.
Typowy scenariusz
Projektant tworzy baner promocyjny z tekstem 'Start Your Free Trial' bezpośrednio w obrazie.
Zespół lokalizacyjny przetłumaczy wszystkie ciągi UI, ale baner na niemieckiej stronie wciąż wyświetla tekst po angielsku.
Wynik: Niemiecka strona docelowa ma irytujący angielski baner. Stworzenie zlokalizowanych bannerów dla 15 języków zajmuje 3 dni pracy przy projektowaniu i opóźnia uruchomienie.
Dlaczego to jest problem?
Typowa strona marketingowa ma 5–10 obrazów z tekstem. Przy 15 językach to 75–150 wariantów obrazów, które trzeba tworzyć, utrzymywać i aktualizować przy każdej zmianie projektu.
Tekst wstawiony w obrazy (PNG, JPG, SVG z wbudowanym tekstem) nie może być wyodrębniony przez narzędzia do tłumaczeń. Każda wersja lokalizowana wymaga ręcznej edycji pliku źródłowego przez projektanta, eksportu i przesłania.
Użytkownicy widzą obrazy z tekstem w obcym języku, a co gorsza, mieszankę przetłumaczonego UI i nieprzetłumaczonych obrazów. To wydaje się niespójne i podważa zaufanie do marki.
Jak to naprawisz
Oddziel tekst od obrazów za pomocą nakładek CSS, SVG z elementami tekstowymi do przetłumaczenia lub dynamiczną generacją obrazów.
Użyj CSS, aby umieścić tekst do przetłumaczenia nad tłem: ustaw warstwę tekstową w pozycji absolutnej nad kontenerem obrazu.
W przypadku infografik lub diagramów używaj SVG-ów z elementami <text> odwołującymi się do kluczy tłumaczeń, zamiast wstawiać surowe ciągi.
Dla zrzutów ekranu aplikacji w materiałach marketingowych zautomatyzuj generowanie zrzutów ekranu narzędziami takimi jak Fastlane (Mobil) lub Playwright (Web), które robią zrzuty w każdej lokalizacji.
Błąd #8: Brakujące tłumaczenia nie są obsługiwane
Tłumaczenia podczas rozwoju są zawsze niekompletne. Nowe funkcje dodają ciągi szybciej, niż tłumacze mogą je przetłumaczyć. Bez solidnego mechanizmu obsługi zapasowego (fallback) brakujące tłumaczenia powodują awarie, puste elementy interfejsu lub surowe klucze tłumaczeń pokazywane użytkownikom.
['Zawsze skonfiguruj co najmniej jeden język zapasowy w ustawieniach i18n', 'Loguj brakujące klucze tłumaczeń do systemu monitoringu w celu śledzenia', 'Ustaw minimalny poziom pokrycia tłumaczeń, zanim dana lokalizacja wejdzie na produkcję']
Zawsze konfiguruj co najmniej jeden język zapasowy w ustawieniach i18n.
Loguj brakujące klucze tłumaczeń do systemu monitorowania w celu śledzenia.
Ustal minimalny poziom pokrycia tłumaczeń, zanim locale będzie mogła przejść na produkcję.
Typowy scenariusz
Programista dodaje nowy dział 'Premium Features' z 15 kluczami tłumaczeń. Angielska wersja jest od razu udostępniana.
Tłumaczenia na francuski nie są jeszcze ukończone. Francuska strona wyświetla surowe klucze: 'premium.feature1.title', 'premium.feature1.description'.
Wynik: Francuscy użytkownicy widzą zepsutą stronę pełną nazw kluczy deweloperskich. Zespół wsparcia otrzymuje dziesiątki raportów o błędach.
Dlaczego to problem
Im większej skali twojej aplikacji, tym większa luka między angielskimi ciągami a tłumaczeniami w innych językach. Aplikacja z 100 językami i 2.000 ciągami może w każdej chwili mieć ponad 10 000 brakujących tłumaczeń.
Bez mechanizmu obsługi zapasowego (fallback) brakujący klucz tłumaczenia zwraca undefined, null lub surowy ciąg klucza (np. 'checkout.confirmButton'). Silniki szablonów mogą zgłaszać błędy, strona może się zawiesić lub nic nie wyświetlać.
Użytkownicy widzą uszkodzony interfejs: puste przyciski, brakujące etykiety lub krypticzne ciągi, takie jak 'nav.settings.title', zamiast prawdziwego tekstu. To mylące i nieprofesjonalne.
Jak to naprawisz
Skonfiguruj solidny łańcuch fallback i monitoruj pokrycie tłumaczeń we wszystkich lokalizacjach.
Skonfiguruj w swoim ustawieniu i18n łańcuch języków zapasowych: nieistniejące klucze francuskie (fr) automatycznie wracają do angielskich (en).
Dodaj obsługę Missing-Key, która loguje nieprzetłumaczone klucze do systemu monitoringu (np. Sentry, Datadog), nie psując doświadczenia użytkownika.
Utwórz pulpit pokrycia tłumaczeń, który śledzi stopień ukończenia dla poszczególnych lokalizacji i blokuje wydania, gdy pokrycie spadnie poniżej wartości progowej (np. 95%).
Błąd nr 9: problemy z kodowaniem znaków
Problemy z kodowaniem znaków to cichy zabójca lokalizacji. Wszystko wygląda na poprawne w języku angielskim i językach europejskich, ale gdy dodasz chiński, japoński, koreański, arabski lub emoji, pojawią się zniekształcone znaki. Te błędy są znane z tego, że trudno je wykryć.
['Używaj wszędzie kodowania UTF-8 — pliki źródłowe, baza danych, odpowiedzi API i meta-tagi HTML', 'Używaj utf8mb4 w MySQL (nie utf8) dla pełnego zakresu Unicode w tym emoji', 'Testuj rzeczywiste treści w CJK, arabskim i emoji, aby wcześnie wykryć problemy z kodowaniem']
Używaj kodowania UTF-8 wszędzie — plików źródłowych, baz danych, odpowiedzi API i tagów meta HTML.
Używaj utf8mb4 w MySQL (nie utf8), aby obsłużyć pełen zakres Unicode, w tym Emoji.
Przetestuj prawdziwą treść w CJK, arabskim i Emoji, aby wcześnie wykryć problemy z kodowaniem.
Typowy scenariusz
Programiści konfigurują bazę danych MySQL z kolacją latin1 (stary standard). Kod źródłowy aplikacji używa UTF-8.
Użytkownicy japońscy rejestrują się pod prawdziwym imieniem. Baza danych zapisuje '田中太郎' jako uszkodzone bajty.
Wynik: Profil użytkownika pokazuje zniekształcony tekst. Co gorsza: wyszukiwanie i sortowanie nie działa dla wszystkich imion CJK, co dotyka tysiące użytkowników.
Dlaczego to jest problem
Problemy z kodowaniem rozchodzą się po całym stosie. Błędnie skonfigurowana kolacja bazy danych może uszkodzić miliony rekordów — naprawa wymaga kosztownych migracji danych.
Niespójność kodowania w całym stosie — UTF-8 w plikach źródłowych, Latin-1 w bazie danych i Windows-1252 w odpowiedzi API — niszczy znaki wielobajtowe. Pojedynczy źle skonfigurowany poziom zmienia '日本語' na '????' lub '日本èª'.
Użytkownicy widzą zniekształcone teksty, znaki zapytania lub puste pola tam, gdzie powinna być ich język. W najgorszym razie dane wprowadzane w formularzach mogą zostać trwale uszkodzone w bazie danych.
Jak to naprawić
Wymuś konsekwent kodowanie UTF-8 we wszystkich warstwach stosu aplikacji.
Ustaw wszystkie pliki źródłowe na UTF-8 (skonfiguruj swój edytor i .editorconfig). Dodaj <meta charset='UTF-8'> w HTML i 'Content-Type: application/json; charset=utf-8' w odpowiedzi API.
Skonfiguruj bazę danych na utf8mb4 (nie tylko utf8, co w MySQL stanowi podzbiór 3 bajtów). Ustaw kolację połączenia na utf8mb4_unicode_ci.
Wybierz czcionki obejmujące twoje docelowe systemy pisma: łacińskie, cyrylica, CJK, arabski, Devanagari. Użyj stosów czcionek systemowych lub Google Fonts z podzbiorami językowymi dla optymalnego ładowania.
Przetestuj swoją implementację i18n.
Test wydłużania długości
Powiększ wszystkie przetłumaczone ciągi o 30-40%, aby zasymulować rozszerzenie tekstu, które występuje w językach o bogatszych treściach, takich jak niemiecki, fiński czy grecki. To obejmuje kontenery o stałej szerokości, przycięte etykiety i przyciski wychodzące poza obszar interfejsu, zanim zaczniesz tłumaczyć. Wiele narzędzi do pseudo-lokalizacji oferuje to jako funkcję wbudowaną.
"Wyślij" → "Ṡééééñðéñ_éxpáñðéð" (40% dłuższy)
Pseudolokalizacja.
Pseudolokalizacja zastępuje każdy znak akcentowanym odpowiednikiem (np. 'a' → 'á') i otacza ciągi znaków znacznikami takimi jak [!! i !!]. Dzięki temu natychmiast widać, które łańcuchy są hardkodowane, a które pochodzą z systemu tłumaczeń. Uruchamiaj pseudolokalizację jako część swojego CI-pipeline, aby automatycznie wychwytywać regresje.
Każdy tekst na ekranie, który NIE jest zawarty w znacznikach [!! !!], jest hardkodowany i musi zostać wydzielony. Ten test wykrywa około 95% pomijanych ciągów znaków w mniej niż minutę.
"Wyślij wiadomość" → "[!! Ñáçḥŕíçḥṫ ṡéñðéñ !!]"
Test układu RTL
Także bez arabskich ani hebrajskich tłumaczeń możesz przetestować RTL-layout, dodając dir='rtl' do elementu korzeniowego HTML. To natychmiast wykryje problemy CSS związane z kierunkiem: źle wyrównane ikony, marginesy po złej stronie, zepsute menu i źle posortowane elementy flex. Uczyń to standardową kontrolą w każdej sprintowej recenzji — przełączenie zajmuje 10 sekund i wykryje problemy, które inaczej wymagałyby tygodni pracy w produkcji.
Checklista i18n
['Wszystkie ciągi widoczne dla użytkownika w plikach zasobów zostały przeniesione', 'Żadna konkatenacja łańcuchów nie używana do tworzenia zdań', 'Zasady liczby mnogiej zaimplementowano przy użyciu ICU MessageFormat lub odpowiednika', 'Formatowanie dat, czasu i liczb używa interfejsów API zależnych od lokalizacji', 'Testowano układ RTL z treścią arabską lub hebrajską', 'Elastyczny interfejs użytkownika bez stałych szerokości przy elementach z tekstem', 'Skonfigurowano i przetestowano język zapasowy przy brakujących kluczach', 'Kodowanie UTF-8 spójne we wszystkich plikach i bazach danych', 'Metadane App Store i Play Store zlokalizowane dla każdego rynku', 'Zaktualizowano zrzuty ekranu i zasoby marketingowe dla każdego języka']