Zadaj pytanie i otrzymaj streszczenie dokumentu, odwołując się do tej strony i wybranego dostawcy AI
Historia wersji
- "Początkowa wersja"v9.5.1026.09.2026
Treść tej strony została przetłumaczona przy użyciu sztucznej inteligencji.
Zobacz ostatnią wersję oryginalnej treści w języku angielskimJeśli masz pomysł na ulepszenie tej dokumentacji, zachęcamy do przesłania pull requesta na GitHubie.
Link do dokumentacji na GitHubieKopiuj dokument Markdown do schowka
Jak zinternacjonalizować aplikację TanStack Start za pomocą Lingui w 2026 roku
Spis treści
Czym jest Lingui?
Lingui to biblioteka i18n zbudowana wokół makr i ekstrakcji komunikatów. Tekst źródłowy piszesz bezpośrednio w komponentach ( t`Hello` , <Trans>Hello</Trans>), polecenie lingui extract zbiera każdy komunikat do katalogów (domyślnie pliki PO), tłumacze je uzupełniają, a wtyczka Vite kompiluje je do kompaktowego kodu JavaScript. Komunikaty używają formatu ICU MessageFormat, więc liczba mnoga i selektory są w pełni obsługiwane.
TanStack Start nie posiada wbudowanej warstwy i18n, dlatego ten przewodnik łączy z nim Lingui od podstaw:
- Makra kompilowane przez Babel za pośrednictwem
@rolldown/plugin-babel(wymagane w przypadku@vitejs/plugin-reactv6 i Vite 8). - Routing regionalny z opcjonalnym segmentem
{-$locale}(/about,/fr/about). - Jeden katalog na język, ładowany na żądanie oraz osobna instancja
I18nna renderowanie, dzięki czemu równoległe żądania SSR nigdy nie współdzielą ustawień językowych. - Kompletne wielojęzyczne SEO: przetłumaczony
<title>i opis, kanoniczny adres URL,hreflangzx-default, Open Graph locales, JSON-LD, sitemap,robots.txt, pre-rendering i zlokalizowane strony 404.
Szukasz innego stosu technologicznego? Zobacz przewodnik TanStack Start + use-intl, przewodnik TanStack Start + Paraglide lub przewodnik TanStack Start + Intlayer.
Używasz Next.js? Zobacz przewodnik Next.js + Lingui. Porównujesz biblioteki? Przeczytaj Lingui kontra Intlayer.
Co benchmark mówi o Lingui w TanStack Start
Benchmark i18n uruchamia tę samą 10-stronicową, 10-języczną aplikację TanStack Start z każdą główną biblioteką i mierzy, co przeglądarka faktycznie pobiera.
Dynamiczne ładowanie JSON
Wczytuje tłumaczenia leniwie w czasie wykonywania
Ograniczony JSON (przestrzenie nazw)
Przestrzenie nazw tłumaczeń na stronę
Benchmark wydajności I18n
Czym jest ta metryka?
Całkowity skompresowany przez gzip rozmiar pakietu biblioteki umiędzynarodowienia. Obejmuje tylko dostawcę i logikę pobierania treści po tree-shakingu i minifikacji.
Dlaczego to jest ważne?
Mniejszy rozmiar biblioteki zmniejsza obciążenie u klienta.
Zobacz jako
Kluczowe dane dla @lingui/core@6.6.0, zmierzone 2026-09-26 (gzip):
Otwórz tabelę w oknie modalnym, aby wyraźnie zobaczyć całą zawartość
| Konfiguracja | Rozmiar biblioteki | JS na stronę | Wyciek innego języka | Wyciek innej strony |
|---|---|---|---|---|
| Brak i18n (aplikacja bazowa) | - | 111.0 KB | 0% | 0% |
| Lingui (konfiguracja z poradnika) | 56.7 KB | 115.2 KB | 9.3% | 0% |
@intlayer/lingui (kompatybilność) | 9.8 KB | 136.7 KB | 9.9% | 0% |
react-intlayer (natywny Intlayer) | 4.5 KB | 126.8 KB | 0% | 0% |
Wnioski:
- Ładuj jeden katalog na język, na żądanie. Pozwala to utrzymać rozmiar stron zbliżony do aplikacji bazowej.
- Środowisko wykonawcze (runtime) pozostaje duże (~57 KB gzip). Adapter kompatybilności
@intlayer/lingui(krok 16) zachowuje Twoje makra i redukuje go do ~10 KB.
Zobacz pełne dane: raport benchmarku TanStack Start oraz repozytorium benchmarku.
Porównanie funkcji w TanStack Start
Jak Lingui wypada w porównaniu z innymi bibliotekami powszechnie używanymi w TanStack Start:
Otwórz tabelę w oknie modalnym, aby wyraźnie zobaczyć całą zawartość
| Funkcja | react-intlayer (Intlayer) | use-intl | Paraglide JS | Lingui |
|---|---|---|---|---|
| Tłumaczenia blisko komponentów | ✅ Współdzielona lokalizacja (co-located) | ❌ Scentralizowany JSON | ❌ Jeden plik JSON na język | ⚠️ Tekst źródłowy w komponentach |
| Integracja z TypeScript | ✅ Automatycznie generowane typy | ✅ Przez AppConfig | ✅ Typowane funkcje komunikatów | ⚠️ Tylko makra |
| Wykrywanie brakujących tłumaczeń | ✅ Błędy typów i ostrzeżenia kompilacji | ⚠️ Fallback w runtime | ⚠️ Powrót do języka bazowego | ⚠️ Powrót do tekstu źródłowego |
| Bogata zawartość (JSX, Markdown) | ✅ Bezpośrednie wsparcie | ⚠️ Tagi przez t.rich | ⚠️ Ciągi znaków | ✅ JSX wewnątrz <Trans> |
| Zlokalizowany routing | ✅ Wbudowany | ❌ Ręczny {-$locale} | ✅ urlPatterns + rewrite routera | ❌ Ręczny {-$locale} |
| Zmiana języka bez przeładowania | ✅ Tak | ✅ Tak | ❌ Pełne przeładowanie strony | ✅ Tak |
| Liczba mnoga (pluralizacja) | ✅ Oparta na wyliczeniach | ✅ ICU | ✅ Warianty | ✅ ICU |
| ICU MessageFormat | ✅ Przez format: "icu" | ✅ Natywny | ⚠️ Przez wtyczkę inlang | ✅ Natywny |
| Formaty zawartości | ✅ .ts, .json, .md, .yaml... | ⚠️ .json | ⚠️ inlang JSON | ✅ PO, JSON, CSV |
| Tłumaczenie AI | ✅ Własny dostawca i klucz | ❌ Nie | ❌ Nie | ❌ Nie |
| Wizualny edytor / CMS | ✅ Lokalny edytor + opcjonalny CMS | ❌ Zewnętrzne platformy | ⚠️ Aplikacje ekosystemu inlang | ❌ Zewnętrzne platformy |
| Narzędzia SEO (hreflang, sitemap) | ✅ Wbudowane | ❌ Ręczne | ⚠️ Zlokalizowane URL, reszta ręczna | ❌ Ręczne |
| Rozmiar runtime (gzip, benchmark) | 4.5 KB | 75.9 KB | 1.8 KB | 56.7 KB |
| Wyciek, optymalna konfig. (język / strona) | 0% / 0% | 0% / 0% | 49.7% / 0% | 8.6% / 0% |
| Brakujące tłumaczenia w CI | ✅ npx intlayer test | ⚠️ Brak wbudowanego | ⚠️ Brak wbudowanego | ✅ lingui compile --strict |
Dane dotyczące rozmiaru runtime i wycieków pochodzą z benchmarku TanStack Start. Wyciek jest mierzony na optymalnej konfiguracji dla każdej biblioteki.
Inne przewodniki po TanStack Start: use-intl, Paraglide JS oraz Intlayer.
Praktyki, które warto stosować
- Ustawiaj
langidirw<html>na podstawie języka trasy, aby były prawidłowe w generowanym przez serwer kodzie HTML. - Utrzymuj jeden adres URL na język z prefiksem, aby każda wersja językowa mogła być indeksowana.
- Twórz jedną instancję
I18nna język, nigdy nie modyfikuj instancji globalnej podczas SSR: dwa jednoczesne żądania mogłyby nadpisać nawzajem swoje ustawienia językowe. - Ładuj tylko aktywny katalog, nigdy nie importuj wszystkich katalogów w kodzie klienta.
- Wybierz jeden styl makr (
useLingui+tw komponentach,msgdla deskryptorów ładowanych leniwie) i trzymaj się go konsekwentnie. Mieszaniet,i18n._,i18n.toraz<Trans>utrudnia czytanie kodu ludziom oraz asystentom AI. - Uruchamiaj
lingui extractw CI, aby żaden nowy komunikat nie trafił na produkcję bez tłumaczenia. - Tłumacz metadane i deklaruj
canonical,hreflangorazx-defaultna każdej stronie. - Generuj wielojęzyczną mapę witryny (sitemap) i robots.txt oraz renderuj wstępnie (pre-render) każdy język.
- Używaj prawdziwych linków dla przełącznika języków, aby roboty indeksujące mogły odkryć każdą wersję językową.
Zobacz nasz przewodnik na temat internacjonalizacji i SEO oraz przewodnik po hreflang.
Przewodnik krok po kroku po konfiguracji Lingui w aplikacji TanStack Start
Oto struktura projektu, którą utworzymy:
Skopiuj kod do schowka
Instalacja zależności
bashKopiuj kodSkopiuj kod do schowka
- @lingui/core / @lingui/react: środowisko uruchomieniowe (runtime),
I18nProvideroraz makra (@lingui/core/macro,@lingui/react/macro). - @lingui/cli: narzędzie
lingui extractdo zbierania komunikatów do katalogów. - @lingui/vite-plugin: kompiluje katalogi
.popodczas importu, dzięki czemulingui compilenie jest potrzebne. - @lingui/babel-plugin-lingui-macro + @rolldown/plugin-babel: przekształcają makra w czasie budowania.
- @lingui/core / @lingui/react: środowisko uruchomieniowe (runtime),
Scentralizuj konfigurację językową
Domyślny język pozostaje bez prefiksu (
/about), a pozostałe języki otrzymują prefiks (/fr/about).src/i18n/config.tsKopiuj kodSkopiuj kod do schowka
Skonfiguruj Lingui
Konfiguracja Lingui korzysta z tej samej listy języków, dzięki czemu katalogi, router i mapa witryny są zawsze w pełni spójne.
lingui.config.tsKopiuj kodSkopiuj kod do schowka
Dodaj skrypty ekstrakcji:
package.jsonKopiuj kodSkopiuj kod do schowka
Skrypt
i18n:checkkończy się błędem w środowisku CI, jeśli komponent zawiera komunikat, który nie został wyekstrahowany i zatwierdzony w repozytorium.Skonfiguruj Vite
W
@vitejs/plugin-reactv6 Babel nie jest już wbudowany.@rolldown/plugin-babeluruchamia wtyczkę makr Lingui, alinguiTransformerBabelPresetprzetwarza tylko pliki importujące makro, co pozwala zachować dużą szybkość budowania.vite.config.tsKopiuj kodSkopiuj kod do schowka
Ładowanie katalogów według języka
Literał szablonowy w
import()pozwala Vite wygenerować jeden fragment (chunk) na katalog, a wtyczka Lingui kompiluje do niego plik.po. Odwiedzający z Francji pobiera wyłącznie katalog francuski.Skompilowane komunikaty są czystymi danymi, więc mogą być zwracane przez loader trasy, serializowane do kodu HTML i ponownie używane podczas hydratacji.
src/i18n/lingui.tsKopiuj kodSkopiuj kod do schowka
Aby TypeScript akceptował importowanie plików
.po, zadeklaruj moduł jednorazowo:src/i18n/po.d.tsKopiuj kodSkopiuj kod do schowka
Utwórz dokument główny (Root Document)
Główna trasa odczytuje opcjonalny parametr języka, aby ustawić
langidirw renderowanym po stronie serwera znaczniku<html>.src/routes/__root.tsxKopiuj kodSkopiuj kod do schowka
Utwórz trasę układu językowego (Locale Layout)
Katalog
{-$locale}tworzy opcjonalny segment ścieżki: zarówno/about, jak i/fr/aboutpasują do/{-$locale}/about. Układ odrzuca nieznane prefiksy, ładuje katalog bieżącego języka i dostarcza dedykowaną instancjęI18n.src/routes/{-$locale}/route.tsxKopiuj kodSkopiuj kod do schowka
Wykorzystaj tłumaczenia na swoich stronach
Pisz tekst źródłowy bezpośrednio w komponencie. Makra przekształcają go w identyfikatory komunikatów podczas budowania, a
lingui extractautomatycznie go pobiera.<Trans>dla zawartości JSX, w tym elementów zagnieżdżonych;useLingui().tdla ciągów znaków (atrybuty, właściwości props);<Plural>dla obsługi form liczby mnogiej w formacie ICU.
src/routes/{-$locale}/about.tsxKopiuj kodSkopiuj kod do schowka
Dynamiczny
import()katalogu jest buforowany przez system modułów, więc wywołanieloadI18nw kilku loaderach nie powoduje podwójnego pobierania katalogu.Ekstrakcja i tłumaczenie komunikatów
Uruchom proces ekstrakcji. Lingui zapisze każdy komunikat do katalogu odpowiedniego języka:
bashKopiuj kodSkopiuj kod do schowka
Następnie przetłumacz pole
msgstrkażdego wpisu:src/locales/fr/messages.poKopiuj kodSkopiuj kod do schowka
src/locales/es/messages.poKopiuj kodSkopiuj kod do schowka
Domyślnie identyfikatory komunikatów są hashami tekstu źródłowego: zmiana tekstu w języku angielskim tworzy nowy komunikat. Używaj jawnych identyfikatorów (
<Trans id="about.title">About us</Trans>) dla tekstów, które często ulegają zmianie.Budowa komponentu zlokalizowanego linku (LocalizedLink)
OpcjonalneKażda trasa znajduje się pod
{-$locale}, dlatego linki muszą przenosić parametr bieżącego języka.src/components/LocalizedLink.tsxKopiuj kodSkopiuj kod do schowka
Zmiana języka wyświetlanej zawartości
OpcjonalneWyrenderuj przełącznik jako linki, aby roboty indeksujące mogły znaleźć każdą wersję językową.
to="."zachowuje bieżącą stronę i podmienia parametr języka. Loader układu językowego pobiera następnie nowy katalog.src/components/LocaleSwitcher.tsxKopiuj kodSkopiuj kod do schowka
Internacjonalizacja metadanych
OpcjonalneKażda wersja językowa może pozycjonować się niezależnie, pod warunkiem że każda strona udostępnia przetłumaczony
<title>i opis, odwołujący się do samej siebie adres kanoniczny, jeden taghreflangna każdy język orazx-default, Open Graph locales i JSON-LD z poleminLanguage. Metadane są tłumaczone w loaderze (krok 8), a ten pomocnik buduje całą resztę:src/i18n/seo.tsKopiuj kodSkopiuj kod do schowka
Internacjonalizacja sitemap i robots.txt
OpcjonalneMapa witryny (sitemap) zawiera każdy adres URL w każdym języku, a każdy wpis deklaruje wszystkie swoje warianty alternatywne za pomocą
xhtml:link. Plikrobots.txtblokuje prywatne ścieżki we wszystkich językach i wskazuje na mapę witryny. Usuń plikpublic/robots.txt, jeśli szablon go utworzył.src/routes/sitemap[.]xml.tsKopiuj kodSkopiuj kod do schowka
src/routes/robots[.]txt.tsKopiuj kodSkopiuj kod do schowka
Wstępne renderowanie (pre-render) każdego języka
OpcjonalneWypisz wszystkie zlokalizowane ścieżki, aby TanStack Start renderował wstępnie wszystkie wersje językowe w czasie budowania:
vite.config.tsKopiuj kodSkopiuj kod do schowka
Przekierowywanie nowych użytkowników i obsługa stron 404
OpcjonalneMiddleware żądań przekierowuje użytkownika wchodzącego na stronę główną
/do preferowanego języka (najpierw plik cookie, następnieAccept-Language). Bezpośrednie linki (deep links) nigdy nie są przekierowywane, dzięki czemu roboty indeksujące i udostępniane adresy URL zawsze otrzymują dokładnie tę stronę, o którą poproszono.src/i18n/negotiateLocale.tsKopiuj kodSkopiuj kod do schowka
src/start.tsKopiuj kodSkopiuj kod do schowka
W przypadku stron 404 trasa typu catch-all renderuje zlokalizowany
notFoundComponentukładu. Oznacz go jakonoindex: React 19 automatycznie przenosi znacznik<meta>do<head>.src/components/NotFound.tsxKopiuj kodSkopiuj kod do schowka
src/routes/{-$locale}/$.tsxKopiuj kodSkopiuj kod do schowka
Zachowaj swoje makra, zmniejsz rozmiar runtime dzięki Intlayer
OpcjonalneAdapter kompatybilności
@intlayer/linguipozwala zachować kod źródłowy bez zmian: makra kompilują się dokładnie tak jak wcześniej, a wygenerowane wywołaniai18n._(),useLingui()i<Trans>są obsługiwane przez skompilowane słowniki Intlayer. W benchmarku rozmiar runtime spada z ~56.7 KB do ~9.8 KB gzip.bashKopiuj kodSkopiuj kod do schowka
Dodaj wtyczkę po transformacji makr, aby tworzyła aliasy
@lingui/corei@lingui/reactwskazujące na adapter:vite.config.tsKopiuj kodSkopiuj kod do schowka
Katalogi są synchronizowane za pomocą wtyczki sync JSON (katalogi JSON) lub wtyczki sync PO (katalogi PO). Zobacz pełną konfigurację w przewodniku kompatybilności z Lingui oraz bezpośrednie porównanie w artykule Lingui kontra @intlayer/lingui.
Zautomatyzuj swoje tłumaczenia za pomocą Intlayer
OpcjonalneLingui ekstrahuje komunikaty, ale ręczne uzupełnianie dziesiątek katalogów zajmuje najwięcej czasu. Intlayer jest darmowy i open source, a jego narzędzia doskonale współpracują z Lingui:
- Tłumacz za pomocą AI przy użyciu własnego klucza API i dostawcy. Zobacz auto fill oraz CLI.
- Zachowaj pliki PO jako pojedyncze źródło prawdy dzięki wtyczce sync PO.
- Testuj brakujące tłumaczenia w środowisku CI. Zobacz testowanie tłumaczeń.
- Przeprowadzaj audyt wdrożonej witryny pod kątem brakujących tagów
hreflang, błędnych adresów kanonicznych i wycieków językowych za pomocą polecenia scan.
Często zadawane pytania
Tak. Lingui nie posiada dedykowanej integracji z TanStack Start, ale jego wtyczka Vite oraz wtyczka makr Babel działają bez problemu. Dwie kluczowe kwestie to uruchamianie makr przez @rolldown/plugin-babel (Vite 8 i @vitejs/plugin-react v6 nie zawierają już Babela) oraz tworzenie osobnej instancji I18n na każdy język zamiast aktywowania globalnej instancji podczas SSR.
Na serwerze jeden proces obsługuje wiele żądań jednocześnie. Wywołanie i18n.activate("fr") na współdzielonym obiekcie zmieniłoby język dla żądania renderowanego równolegle w języku angielskim. setupI18n tworzy odizolowaną instancję dla każdego języka, co jest w pełni bezpieczne.
Nie. Wtyczka @lingui/vite-plugin kompiluje katalogi .po w momencie ich importowania. Wystarczy uruchamiać lingui extract, aby zbierać nowe komunikaty.
Zadeklaruj je za pomocą makra msg, a następnie przetłumacz w loaderze trasy za pomocą i18n._(msg`...`). Loader zwraca czyste ciągi znaków, dzięki czemu funkcja head() pozostaje synchroniczna, a wartości są serializowane na potrzeby hydratacji. Kroki 8 i 12 pokazują pełną konfigurację.
Benchmark wskazuje ~56.7 KB gzip dla środowiska uruchomieniowego (runtime). Przy ładowaniu jednego katalogu na język na żądanie strony ważą ~115 KB w porównaniu do 111 KB bez i18n. Statyczne zaimportowanie wszystkich katalogów zwiększa ten rozmiar do ~152 KB.
Tak. Adapter @intlayer/lingui pozwala zachować makra i podmienia środowisko uruchomieniowe. Następnie możesz stopniowo migrować komponenty do useIntlayer. Zobacz adaptery kompatybilności.
Komentarze
Nie ma jeszcze komentarzy. Bądź pierwszą osobą, która podzieli się swoimi przemyśleniami.
