Ajukan pertanyaan Anda dan dapatkan ringkasan dokumen dengan merujuk halaman ini dan penyedia AI pilihan Anda
Riwayat Versi
- "Versi awal"v9.5.1026/9/2026
Konten halaman ini diterjemahkan menggunakan AI.
Lihat versi terakhir dari konten aslinya dalam bahasa InggrisJika Anda memiliki ide untuk meningkatkan dokumentasi ini, silakan berkontribusi dengan mengajukan pull request di GitHub.
Tautan GitHub ke dokumentasiSalin Markdown dokumentasi ke clipboard
Cara menginternasionalisasi aplikasi TanStack Start Anda menggunakan Lingui pada tahun 2026
Daftar Isi
Apa itu Lingui?
Lingui adalah library i18n yang dibangun di sekitar makro dan ekstraksi pesan. Anda menulis teks sumber secara langsung di komponen Anda ( t`Hello` , <Trans>Hello</Trans>), lingui extract mengumpulkan setiap pesan ke dalam katalog (file PO secara default), penerjemah mengisinya, dan plugin Vite mengompilasinya menjadi JavaScript yang ringkas. Pesan menggunakan ICU MessageFormat, sehingga bentuk jamak (plurals) dan pilihan (selects) didukung.
TanStack Start tidak menyertakan lapisan i18n bawaan, jadi panduan ini menghubungkan Lingui dari awal:
- Makro dikompilasi oleh Babel melalui
@rolldown/plugin-babel(diperlukan dengan@vitejs/plugin-reactv6 dan Vite 8). - Perutean lokal dengan segmen opsional
{-$locale}(/about,/fr/about). - Satu katalog per lokal, dimuat sesuai kebutuhan (on demand), dan satu instance
I18nper render sehingga permintaan SSR bersamaan tidak pernah berbagi lokal yang sama. - SEO multibahasa lengkap:
<title>dan deskripsi yang diterjemahkan, URL kanonikal,hreflangdenganx-default, lokal Open Graph, JSON-LD, sitemap,robots.txt, pre-rendering, dan halaman 404 yang terlokalisasi.
Mencari stack lain? Lihat panduan TanStack Start + use-intl, panduan TanStack Start + Paraglide, atau panduan TanStack Start + Intlayer.
Menggunakan Next.js? Lihat panduan Next.js + Lingui. Membandingkan library? Baca Lingui vs Intlayer.
Apa yang dikatakan benchmark tentang Lingui di TanStack Start
Benchmark i18n menjalankan aplikasi TanStack Start 10 halaman, 10 lokal yang sama dengan setiap library utama dan mengukur apa yang sebenarnya diunduh oleh browser.
Pemuatan JSON dinamis
Memuat terjemahan secara lambat saat runtime
JSON cakupan (namespacing)
Namespace terjemahan per halaman
Tolok Ukur Performa I18n
Apa metrik ini?
Total ukuran kompresi gzip dari bundel pustaka internasionalisasi. Ini hanya mencakup penyedia dan logika pengambilan konten setelah tree-shaking dan minifikasi.
Mengapa ini penting?
Ukuran pustaka yang lebih kecil mengurangi muatan JavaScript awal, yang mengarah pada waktu unduh dan eksekusi yang lebih cepat pada klien.
Lihat sebagai
Angka-angka utama untuk @lingui/core@6.6.0, diukur pada 2026-09-26 (gzip):
Buka tabel dalam modal untuk melihat semua isi data dengan jelas
| Pengaturan | Ukuran library | JS per halaman | Kebocoran lokal lain | Kebocoran halaman lain |
|---|---|---|---|---|
| Tanpa i18n (aplikasi dasar) | - | 111.0 KB | 0% | 0% |
| Lingui (pengaturan panduan ini) | 56.7 KB | 115.2 KB | 9.3% | 0% |
@intlayer/lingui (kompatibilitas) | 9.8 KB | 136.7 KB | 9.9% | 0% |
react-intlayer (Intlayer native) | 4.5 KB | 126.8 KB | 0% | 0% |
Hal penting yang dapat dipelajari:
- Muat satu katalog per lokal, sesuai kebutuhan. Ini menjaga ukuran halaman mendekati ukuran aplikasi dasar.
- Ukuran runtime tetap besar (~57 KB gzip). Adaptor kompatibilitas
@intlayer/lingui(langkah 16) mempertahankan makro Anda dan memotong ukurannya menjadi ~10 KB.
Lihat data selengkapnya: Laporan benchmark TanStack Start, dan repositori benchmark.
Perbandingan fitur di TanStack Start
Perbandingan Lingui dengan library lain yang biasa digunakan di TanStack Start:
Buka tabel dalam modal untuk melihat semua isi data dengan jelas
| Fitur | react-intlayer (Intlayer) | use-intl | Paraglide JS | Lingui |
|---|---|---|---|---|
| Terjemahan dekat komponen | ✅ Terlokalisasi berdampingan (co-located) | ❌ JSON terpusat | ❌ Satu file JSON per lokal | ⚠️ Teks sumber dalam komponen |
| Integrasi TypeScript | ✅ Tipe yang dibuat secara otomatis | ✅ Melalui AppConfig | ✅ Fungsi pesan bertipe | ⚠️ Hanya makro |
| Deteksi terjemahan yang hilang | ✅ Kesalahan tipe dan peringatan build | ⚠️ Fallback runtime | ⚠️ Fallback ke lokal dasar | ⚠️ Fallback ke teks sumber |
| Konten kaya (JSX, Markdown) | ✅ Dukungan langsung | ⚠️ Tag via t.rich | ⚠️ String | ✅ JSX di dalam <Trans> |
| Perutean terlokalisasi | ✅ Bawaan (built-in) | ❌ Manual {-$locale} | ✅ urlPatterns + router rewrite | ❌ Manual {-$locale} |
| Penggantian lokal tanpa reload | ✅ Ya | ✅ Ya | ❌ Muat ulang halaman penuh | ✅ Ya |
| Pluralisasi | ✅ Berbasis enumerasi | ✅ ICU | ✅ Varian | ✅ ICU |
| ICU MessageFormat | ✅ Melalui format: "icu" | ✅ Native | ⚠️ Melalui plugin inlang | ✅ Native |
| Format konten | ✅ .ts, .json, .md, .yaml... | ⚠️ .json | ⚠️ inlang JSON | ✅ PO, JSON, CSV |
| Terjemahan AI | ✅ Penyedia dan kunci API Anda sendiri | ❌ Tidak | ❌ Tidak | ❌ Tidak |
| Editor visual / CMS | ✅ Editor lokal + CMS opsional | ❌ Platform eksternal | ⚠️ Aplikasi ekosistem inlang | ❌ Platform eksternal |
| Helper SEO (hreflang, sitemap) | ✅ Bawaan (built-in) | ❌ Manual | ⚠️ URL terlokalisasi, sisanya manual | ❌ Manual |
| Ukuran runtime (gzip, benchmark) | 4.5 KB | 75.9 KB | 1.8 KB | 56.7 KB |
| Kebocoran, setup terbaik (lokal / halaman) | 0% / 0% | 0% / 0% | 49.7% / 0% | 8.6% / 0% |
| Terjemahan hilang di CI | ✅ npx intlayer test | ⚠️ Tidak bawaan | ⚠️ Tidak bawaan | ✅ lingui compile --strict |
Angka ukuran runtime dan kebocoran berasal dari benchmark TanStack Start. Kebocoran diukur pada pengaturan terbaik dari setiap library.
Panduan TanStack Start lainnya: use-intl, Paraglide JS, dan Intlayer.
Praktik terbaik yang harus Anda ikuti
- Tetapkan
langdandirpada<html>dari lokal rute, sehingga atribut tersebut benar dalam HTML server. - Pertahankan satu URL per lokal dengan awalan (prefix), sehingga setiap versi bahasa dapat diindeks.
- Buat satu instance
I18nper lokal, jangan pernah mengubah instance global selama SSR: dua permintaan bersamaan dapat menimpa lokal satu sama lain. - Muat hanya katalog yang aktif, jangan pernah mengimpor semuanya dalam kode klien.
- Pilih satu gaya makro (
useLingui+tdalam komponen,msguntuk deskriptor lazy) dan konsisten menggunakannya. Mencampurt,i18n._,i18n.t, dan<Trans>membuat kode lebih sulit dibaca oleh manusia dan asisten AI. - Jalankan
lingui extractdi CI agar pesan baru tidak pernah dirilis tanpa diterjemahkan. - Terjemahkan metadata Anda, dan deklarasikan
canonical,hreflang, danx-defaultdi setiap halaman. - Buat sitemap multibahasa dan robots.txt, dan lakukan pre-render untuk setiap lokal.
- Gunakan tautan nyata untuk pengalih lokal, sehingga perayap (crawlers) dapat menemukan setiap bahasa.
Lihat panduan kami tentang internasionalisasi dan SEO dan panduan hreflang.
Panduan Langkah demi Langkah untuk Menyiapkan Lingui dalam Aplikasi TanStack Start
Berikut struktur proyek yang akan kita buat:
Salin kode ke clipboard
Pasang Dependensi
bashSalin kodeSalin kode ke clipboard
- @lingui/core / @lingui/react: runtime,
I18nProviderdan makro (@lingui/core/macro,@lingui/react/macro). - @lingui/cli:
lingui extractuntuk mengumpulkan pesan ke dalam katalog. - @lingui/vite-plugin: mengompilasi katalog
.posaat diimpor, sehinggalingui compiletidak diperlukan. - @lingui/babel-plugin-lingui-macro + @rolldown/plugin-babel: mentransformasikan makro saat waktu build.
- @lingui/core / @lingui/react: runtime,
Pusatkan Konfigurasi Lokal Anda
Lokal default tetap tanpa awalan (
/about), lokal lain memiliki awalan (/fr/about).src/i18n/config.tsSalin kodeSalin kode ke clipboard
Konfigurasikan Lingui
Konfigurasi Lingui menggunakan kembali daftar lokal yang sama, sehingga katalog, router, dan sitemap selalu selaras.
lingui.config.tsSalin kodeSalin kode ke clipboard
Tambahkan skrip ekstraksi:
package.jsonSalin kodeSalin kode ke clipboard
i18n:checkgagal di CI ketika suatu komponen berisi pesan yang belum diekstrak dan di-commit.Konfigurasikan Vite
Dengan
@vitejs/plugin-reactv6, Babel tidak lagi disertakan secara bawaan.@rolldown/plugin-babelmenjalankan plugin makro Lingui, danlinguiTransformerBabelPresethanya memproses file yang mengimpor makro, menjaga proses build tetap cepat.vite.config.tsSalin kodeSalin kode ke clipboard
Muat Katalog per Lokal
Literal template di
import()memungkinkan Vite memancarkan satu chunk per katalog, dan plugin Lingui mengompilasi file.poke dalamnya. Pengunjung berbahasa Prancis hanya mengunduh katalog bahasa Prancis.Pesan yang dikompilasi adalah data biasa, sehingga dapat dikembalikan oleh loader rute, diserialisasikan ke dalam HTML, dan digunakan kembali saat hidrasi.
src/i18n/lingui.tsSalin kodeSalin kode ke clipboard
Agar TypeScript menerima impor
.po, deklarasikan modul sekali:src/i18n/po.d.tsSalin kodeSalin kode ke clipboard
Buat Dokumen Root
Rute root membaca parameter lokal opsional untuk mengatur
langdandirpada<html>yang dirender di server.src/routes/__root.tsxSalin kodeSalin kode ke clipboard
Buat Rute Tata Letak Lokal
Folder
{-$locale}membuat segmen jalur opsional:/aboutdan/fr/aboutkeduanya cocok dengan/{-$locale}/about. Tata letak menolak awalan yang tidak dikenal, memuat katalog lokal saat ini, dan menyediakan instanceI18nkhusus.src/routes/{-$locale}/route.tsxSalin kodeSalin kode ke clipboard
Gunakan Terjemahan di Halaman Anda
Tulis teks sumber di dalam komponen. Makro mengubahnya menjadi ID pesan saat waktu build, dan
lingui extractmengumpulkannya.<Trans>untuk konten JSX, termasuk elemen bersarang;useLingui().tuntuk string (atribut, props);<Plural>untuk bentuk jamak ICU.
src/routes/{-$locale}/about.tsxSalin kodeSalin kode ke clipboard
Impor dinamis
import()dari suatu katalog di-cache oleh sistem modul, jadi memanggilloadI18ndi beberapa loader tidak mengunduh katalog dua kali.Ekstrak dan Terjemahkan Pesan Anda
Jalankan ekstraksi. Lingui menulis setiap pesan ke dalam setiap katalog lokal:
bashSalin kodeSalin kode ke clipboard
Kemudian terjemahkan
msgstrdari setiap entri:src/locales/fr/messages.poSalin kodeSalin kode ke clipboard
src/locales/es/messages.poSalin kodeSalin kode ke clipboard
Secara default, ID pesan adalah hash dari teks sumber: mengubah teks bahasa Inggris akan membuat pesan baru. Gunakan ID eksplisit (
<Trans id="about.title">About us</Trans>) untuk teks yang sering berubah.Bangun Komponen Tautan Terlokalisasi
OpsionalSetiap rute berada di bawah
{-$locale}, sehingga tautan harus membawa parameter lokal saat ini.src/components/LocalizedLink.tsxSalin kodeSalin kode ke clipboard
Ubah Bahasa Konten Anda
OpsionalTampilkan pengalih sebagai tautan, sehingga perayap menemukan setiap versi bahasa.
to="."mempertahankan halaman saat ini dan mengganti parameter lokal. Loader dari tata letak lokal kemudian mengambil katalog baru.src/components/LocaleSwitcher.tsxSalin kodeSalin kode ke clipboard
Internasionalisasikan Metadata Anda
OpsionalSetiap versi bahasa dapat memiliki peringkat tersendiri, asalkan setiap halaman menampilkan
<title>dan deskripsi yang diterjemahkan, URL kanonikal yang merujuk pada diri sendiri, satuhreflangper lokal ditambahx-default, lokal Open Graph, dan JSON-LD denganinLanguage. Metadata diterjemahkan di loader (langkah 8), dan helper ini menyusun sisanya:src/i18n/seo.tsSalin kodeSalin kode ke clipboard
Internasionalisasikan Sitemap dan robots.txt Anda
OpsionalSitemap mencantumkan setiap URL dari setiap lokal, dengan setiap entri mendeklarasikan semua alternatifnya menggunakan
xhtml:link.robots.txtmemblokir rute privat di setiap bahasa dan mengarah ke sitemap. Hapuspublic/robots.txtjika starter membuatnya.src/routes/sitemap[.]xml.tsSalin kodeSalin kode ke clipboard
src/routes/robots[.]txt.tsSalin kodeSalin kode ke clipboard
Lakukan Pre-render untuk Setiap Lokal
OpsionalDaftarkan setiap jalur terlokalisasi sehingga TanStack Start melakukan pre-render untuk semua versi bahasa pada saat build:
vite.config.tsSalin kodeSalin kode ke clipboard
Arahkan Pengunjung Pertama Kali dan Tangani Halaman 404
OpsionalMiddleware permintaan mengarahkan pengunjung yang mendarat di
/ke bahasa pilihan mereka (cookie terlebih dahulu, kemudianAccept-Language). Deep link tidak pernah dialihkan, sehingga perayap dan URL yang dibagikan selalu mendapatkan halaman yang diminta.src/i18n/negotiateLocale.tsSalin kodeSalin kode ke clipboard
src/start.tsSalin kodeSalin kode ke clipboard
Untuk halaman 404, rute catch-all merender
notFoundComponentterlokalisasi dari tata letak. Tandai dengannoindex: React 19 mengangkat tag<meta>ke dalam<head>.src/components/NotFound.tsxSalin kodeSalin kode ke clipboard
src/routes/{-$locale}/$.tsxSalin kodeSalin kode ke clipboard
Pertahankan Makro Anda, Kurangi Ukuran Runtime dengan Intlayer
OpsionalAdaptor kompatibilitas
@intlayer/linguimempertahankan kode sumber Anda tanpa perubahan: makro dikompilasi persis seperti sebelumnya, dan panggilani18n._(),useLingui(), serta<Trans>yang dihasilkan dilayani oleh kamus Intlayer yang dikompilasi. Dalam benchmark, ukuran runtime berkurang dari ~56.7 KB menjadi ~9.8 KB gzip.bashSalin kodeSalin kode ke clipboard
Tambahkan plugin setelah transformasi makro, sehingga meng-alias
@lingui/coredan@lingui/reactke adaptor:vite.config.tsSalin kodeSalin kode ke clipboard
Katalog disinkronkan dengan plugin sync JSON (katalog JSON) atau plugin sync PO (katalog PO). Lihat konfigurasi lengkapnya di panduan kompatibilitas Lingui, dan perbandingan berdampingan di Lingui vs @intlayer/lingui.
Otomatiskan Terjemahan Anda Menggunakan Intlayer
OpsionalLingui mengekstrak pesan, tetapi mengisi puluhan katalog secara manual adalah hal yang memakan sebagian besar waktu. Intlayer bersifat gratis dan open source, dan perkakasnya bekerja berdampingan dengan Lingui:
- Terjemahkan dengan AI menggunakan kunci API dan penyedia Anda sendiri. Lihat auto fill dan CLI.
- Pertahankan file PO Anda sebagai sumber kebenaran (source of truth) dengan plugin sync PO.
- Uji terjemahan yang hilang di CI. Lihat menguji terjemahan Anda.
- Audit situs Anda yang telah di-deploy untuk memeriksa
hreflangyang hilang, kanonikal yang salah, dan kebocoran lokal dengan perintah scan.
Pertanyaan yang Sering Diajukan
Ya. Lingui tidak memiliki integrasi khusus bawaan untuk TanStack Start, tetapi plugin Vite dan plugin makro Babel miliknya dapat langsung berfungsi. Dua hal penting yang harus diperhatikan adalah menjalankan makro melalui @rolldown/plugin-babel (Vite 8 dan @vitejs/plugin-react v6 tidak lagi menyertakan Babel), dan membuat satu instance I18n per lokal daripada mengaktifkan instance global selama SSR.
Di server, satu proses merender banyak permintaan secara bersamaan. Memanggil i18n.activate("fr") pada objek bersama akan mengubah bahasa permintaan yang sedang dirender dalam bahasa Inggris secara paralel. setupI18n membuat instance terisolasi per lokal, yang aman dari kondisi tersebut.
Tidak. @lingui/vite-plugin mengompilasi katalog .po saat diimpor. Anda hanya perlu menjalankan lingui extract untuk mengumpulkan pesan baru.
Deklarasikan dengan makro msg, dan terjemahkan di loader rute dengan i18n._(msg`...`). Loader mengembalikan string biasa, sehingga head() tetap sinkron dan nilainya diserialisasikan untuk hidrasi. Langkah 8 dan langkah 12 menunjukkan konfigurasi lengkapnya.
Benchmark mengukur ~56.7 KB gzip untuk runtime. Dengan satu katalog per lokal yang dimuat sesuai kebutuhan, ukuran halaman sekitar ~115 KB dibandingkan 111 KB tanpa i18n. Mengimpor semua katalog secara statis meningkatkannya menjadi ~152 KB.
Ya. Adaptor @intlayer/lingui mempertahankan makro dan menukar runtime. Anda kemudian dapat memindahkan komponen ke useIntlayer satu per satu. Lihat adaptor kompatibilitas.
Komentar
Belum ada komentar. Jadilah yang pertama membagikan pemikiran Anda.
