Ajukan pertanyaan Anda dan dapatkan ringkasan dokumen dengan merujuk halaman ini dan penyedia AI pilihan Anda
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
next-intl VS Intlayer: Tolok Ukur Internasionalisasi (i18n) React & Next.js

next-intl adalah pustaka i18n paling populer untuk Next.js. Intlayer adalah alternatif berbasis kompiler dengan cakupan komponen. Keduanya melokalkan aplikasi App Router. Pertanyaannya adalah berapa biaya masing-masing setelah aplikasi dibangun.
Artikel ini bukan tutorial. Ini adalah perbandingan yang didukung oleh angka dari Benchmark Bloom, rangkaian tolok ukur sumber terbuka yang membangun aplikasi yang sama dengan setiap pustaka dan mengukur apa yang sebenarnya diunduh dan dijalankan peramban.
tl;dr: Pada aplikasi Next.js yang sama,next-intlmenambahkan +12.6 KB gzip JavaScript di setiap halaman, dibandingkan dengan +0.3 KB untuk Intlayer. Tanpa upaya tambahan,next-intlmengirimkan ~90% string halaman luar pada setiap halaman. Mencapai 0% kebocoran dengannext-intlmembutuhkan namespace danpick(messages, [...])per halaman. Intlayer mencapai 0% secara default, karena kompilernya mencakup konten per komponen. Jika Anda menginginkan APInext-intldengan output Intlayer, adaptor@intlayer/next-intlberukuran 147.5 KB per halaman dibandingkan 153.6 KB dengan aslinya.
Ringkasan
- next-intl - Standar komunitas Next.js. Kamus JSON terpusat per bahasa, dukungan penuh ICU MessageFormat, dan integrasi mendalam dengan penanganan permintaan serta routing Next.js.
- Intlayer - Model konten yang berpusat pada komponen. File
.content.tsberada tepat di sebelah komponennya, kompiler build-time melakukan tree-shaking dan lazy loading per komponen dan per lokal, serta menghasilkan tipe TypeScript yang ketat secara otomatis.
Buka tabel dalam modal untuk melihat semua isi data dengan jelas
Lencana diperbarui secara otomatis.
Perbandingan fitur berdampingan
Buka tabel dalam modal untuk melihat semua isi data dengan jelas
| Fitur | Intlayer (react-intlayer / next-intlayer) | next-intl (next-intl / use-intl) |
|---|---|---|
| Terjemahan dekat komponen | ✅ Ya, .content.ts berada di samping setiap komponen | ❌ Kamus JSON terpusat di folder messages/ |
| Integrasi TypeScript | ✅ Tipe ketat dihasilkan otomatis dari konten | ⚠️ Didukung lewat konfigurasi manual global.d.ts |
| Deteksi terjemahan yang hilang | ✅ Error TypeScript + error/peringatan saat build | ⚠️ Runtime mengembalikan kunci atau melempar error tergantung konfigurasi |
| Konten kaya (JSX / Markdown / komponen) | ✅ Dukungan langsung | ⚠️ Melalui t.rich() dengan pemetaan komponen |
| Dukungan ICU MessageFormat | ⚠️ Sedang dikembangkan | ✅ Ya, dukungan penuh ICU |
| Komponen server sinkron | ✅ useIntlayer dari next-intlayer/server bekerja di komponen server turunan | ❌ Memerlukan penerusan terjemahan melalui props dari server asinkron |
| Tree-shaking | ✅ Otomatis per komponen dan per lokal | ⚠️ Memerlukan pemisahan namespace manual dan penggunaan pick() |
| Pemuatan lambat (Lazy loading) | ✅ Satu baris konfigurasi (importMode: 'dynamic') | ⚠️ Memerlukan impor dinamis manual di getRequestConfig |
| Visual Editor / CMS | ✅ Visual Editor gratis + CMS opsional | ❌ Tidak ada |
| Terjemahan bertenaga AI | ✅ Terintegrasi, menggunakan kunci API Anda sendiri | ❌ Tidak ada |
| Server MCP & Keterampilan Agen | ✅ Ya | ❌ Tidak ada |
Tolok ukur
Apa yang diukur
Rangkaian pengujian Benchmark Bloom membangun aplikasi yang sama dengan setiap pustaka: 10 halaman (home, about, blog, careers, contact, FAQ, pricing, products, settings, team), 10 lokal (en, fr, es, de, it, pt, zh, ja, ko, ru), komponen identik, dan konten identik. Halaman diukur dalam en dan fr. Setiap pustaka diuji hingga empat strategi pemuatan:
Buka tabel dalam modal untuk melihat semua isi data dengan jelas
| Strategi | Deskripsi | Siapa yang menggunakan |
|---|---|---|
| static | Semua lokal dan semua halaman dibundel bersama di awal | Prototipe cepat, kode hasil AI |
| dynamic | Hanya lokal aktif yang dimuat, tetapi semua halaman sekaligus | Mayoritas proyek |
| scoped-static | Namespace per rute, tanpa lazy loading | Jarang |
| scoped-dynamic | Namespace per rute + lazy loading. Hanya halaman aktif pada lokal aktif yang dikirim | Aplikasi dengan anggaran kinerja ketat |
Intlayer tidak memerlukan varian "scoped": kompiler otomatis membatasi konten per komponen, sehingga baris static dan dynamic sudah ter-scope secara bawaan.
Untuk setiap build, pengujian mencatat:
- Ukuran pustaka (Lib size): ukuran gzip dari komponen kosong yang hanya mengimpor pustaka i18n.
- JS Halaman (Page JS): JavaScript gzip terunduh per halaman.
- % kebocoran lokal (Locale leak %): proporsi string yang bukan milik lokal yang sedang aktif.
- % kebocoran halaman (Page leak %): proporsi string yang bukan milik halaman yang sedang diakses.
- Rata-rata komponen (Component avg): ukuran gzip rata-rata dari setiap komponen yang dikompilasi terisolasi.
- Reaktivitas E2E: waktu antara pergantian lokal hingga pembaruan
html[lang]di DOM. - Hidrasi: durasi fase hidrasi React.
Angka di bawah ini berasal dari pengujian bertanggal 2026-09-12 dengannext-intl4.14.2 danintlayer9.5.1.
Hasil pada Next.js (App Router)
Pilih metrik dan pustaka yang penting bagi Anda:
Metrik
Pemuatan JSON dinamis
Memuat terjemahan secara lambat saat runtime
JSON cakupan (namespacing)
Namespace terjemahan per halaman
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
Buka tabel dalam modal untuk melihat semua isi data dengan jelas
| Pustaka | Strategi | Ukuran Lib (gz) | Rata-rata JS Halaman (gz) | Bocor Lokal | Bocor Halaman | Rata-rata Komponen (gz) | Reaktivitas E2E | Hidrasi |
|---|---|---|---|---|---|---|---|---|
| base (tanpa i18n) | - | 0.0 KB | 141.0 KB | 0.0% | 0.0% | 0.9 KB | 13.4 ms | 11.8 ms |
next-intl | static | 14.7 KB | 153.6 KB | 4.2% | 89.8% | 21.8 KB | 16.0 ms | 14.7 ms |
next-intl | dynamic | 14.7 KB | 153.6 KB | 9.7% | 89.9% | 21.8 KB | 15.6 ms | 14.8 ms |
next-intl | scoped-static | 14.7 KB | 153.6 KB | 0.0% | 0.0% | 80.1 KB | 17.9 ms | 17.4 ms |
next-intl | scoped-dynamic | 14.7 KB | 153.6 KB | 0.0% | 0.0% | 22.9 KB | 17.8 ms | 16.8 ms |
next-intlayer | static | 5.5 KB | 141.3 KB | 0.0% | 0.0% | 8.5 KB | 15.5 ms | 16.9 ms |
next-intlayer | dynamic | 5.5 KB | 141.3 KB | 0.0% | 0.0% | 6.9 KB | 15.3 ms | 15.9 ms |
@intlayer/next-intl (kompat) | static | 8.0 KB | 147.5 KB | 0.0% | 0.0% | 8.1 KB | 14.5 ms | 12.8 ms |
@intlayer/next-intl (kompat) | dynamic | 8.0 KB | 148.7 KB | 0.0% | 0.0% | 8.1 KB | 11.7 ms | 12.8 ms |
Cara membaca hasil
- Biaya runtime. Aplikasi dasar berukuran 141.0 KB per halaman.
next-intlmeningkatkannya menjadi 153.6 KB (+12.6 KB gzip di setiap halaman), sedangkan Intlayer hanya 141.3 KB (+0.3 KB). - Kebocoran. Dalam pengaturan yang paling sering digunakan (
staticdandynamic),next-intlmengirimkan ~90% string halaman lain di setiap halaman, karena seluruhen.jsonmasuk ke penyedia klien. Menghilangkannya membutuhkan pekerjaan pemisahan manual yang teliti. Intlayer langsung 0% secara otomatis. - Ukuran komponen. Komponen yang memanggil
useTranslations()menghasilkan rata-rata 21.8 KB; komponen yang sama denganuseIntlayer()hanya 6.9 KB.
Tabel lengkap, setiap pustaka dan strategi, dalam laporan benchmark Next.js.
Hasil pada TanStack Start (use-intl)
use-intl adalah inti independen framework dari next-intl. API yang sama, format pesan yang sama. Membandingkannya dengan intlayer di TanStack Start menghilangkan bagian khusus Next.js dari persamaan.
Buka tabel dalam modal untuk melihat semua isi data dengan jelas
| Pustaka | Strategi | Ukuran Lib (gz) | Rata-rata JS Halaman (gz) | Bocor Lokal | Bocor Halaman | Rata-rata Komponen (gz) | Reaktivitas E2E |
|---|---|---|---|---|---|---|---|
| base (tanpa i18n) | - | 0.0 KB | 111.0 KB | 0.0% | 0.0% | 0.7 KB | 8.1 ms |
use-intl | static | 14.1 KB | 179.8 KB | 50.0% | 89.8% | 76.0 KB | 6.7 ms |
use-intl | dynamic | 14.1 KB | 119.4 KB | 0.0% | 89.8% | 75.9 KB | 7.0 ms |
use-intl | scoped-static | 14.1 KB | 128.7 KB | 0.0% | 0.0% | 87.1 KB | 20.9 ms |
use-intl | scoped-dynamic | 14.1 KB | 128.7 KB | 0.0% | 0.0% | 87.1 KB | 13.3 ms |
intlayer | static | 5.0 KB | 125.8 KB | 50.0% | 0.0% | 8.1 KB | 3.2 ms |
intlayer | dynamic | 5.0 KB | 118.6 KB | 0.0% | 0.0% | 6.3 KB | 3.6 ms |
@intlayer/use-intl (kompat) | dynamic | 7.3 KB | 129.7 KB | 0.0% | 0.0% | 9.3 KB | 8.7 ms |
Cara membaca hasil
- Pengaturan sederhana
use-intlmengirimkan 68.8 KB lebih banyak JS per halaman dibandingkan aplikasi dasar. - Dalam mode
dynamic,use-intlmencapai 119.4 KB, namun masih membawa 89.8% kebocoran halaman. - Perbedaan arsitektur sangat terlihat pada ukuran komponen: 76-87 KB pada
use-intlberbanding 6-8 KB pada Intlayer. - Pergantian lokal 2x-4x lebih cepat dengan Intlayer (3 ms vs 7-21 ms).
Tabel lengkap dalam laporan benchmark TanStack Start.
Mengapa ada perbedaan? Katalog terpusat vs kamus terkompilasi

next-intl mengikuti model klasik: satu JSON per lokal, dimuat dalam getRequestConfig, diteruskan ke NextIntlClientProvider, dan dibaca lewat t("namespace.key").
Salin kode ke clipboard
Runtime tidak dapat memprediksi kunci apa yang akan digunakan halaman, sehingga mengirimkan seluruh katalog adalah langkah paling aman.
Biaya kegagalan mencapainya tumbuh pada dua sumbu sekaligus, halaman dan lokalitas:

Intlayer membalikkan model tersebut. Konten dideklarasikan langsung di sebelah komponen:
Salin kode ke clipboard
Saat build, kompiler melihat komponen mana yang mengimpor kamus mana, dan hanya membundel kamus tersebut untuk lokal yang aktif.
Untuk mendapatkan angka pada barisdynamic, aturdictionary.importMode: 'dynamic'diintlayer.config.ts. Lihat panduan optimasi bundle.
Pengalaman pengembang
Komponen klien
Salin kode ke clipboard
Salin kode ke clipboard
Ingatlah untuk menyertakan namespacecounterdalam pesan yang diteruskan keNextIntlClientProviderdi setiap halaman yang merender komponen ini.
Salin kode ke clipboard
Salin kode ke clipboard
Tidak ada yang perlu didaftarkan di halaman: komponen membawa kontennya sendiri.
Komponen server sinkron
Elemen UI bersama (navbar, footer, kartu) sering kali merupakan komponen server yang dirender sebagai anak dari komponen klien, sehingga tidak boleh bersifat async.
Salin kode ke clipboard
Halaman harus memanggil await getTranslations("counter") dan await getFormatter(), lalu meneruskan hasilnya ke bawah sebagai props. Komponen tidak lagi mandiri.
Salin kode ke clipboard
Metadata
Salin kode ke clipboard
Salin kode ke clipboard
Pertahankan API next-intl, dapatkan hasil Intlayer
Anda tidak perlu menulis ulang komponen untuk mendapatkan angka performa di atas. Paket @intlayer/next-intl adalah adaptor siap pakai: ia mempertahankan useTranslations, getTranslations, useFormatter, t.rich(), dan bentuk jamak ICU, sambil menyajikannya dari kamus Intlayer yang dikompilasi oleh kompiler Intlayer.
Salin kode ke clipboard
Dalam pengujian, build kompatibilitas dari aplikasi yang sama turun dari 153.6 KB ke 147.5 KB per halaman, ukuran komponen turun dari 21.8 KB ke 8.1 KB, dan kebocoran halaman turun dari ~90% ke 0%, tanpa mengubah kode aplikasi. File messages/{locale}.json yang ada dapat tetap menjadi sumber data utama melalui plugin sinkronisasi JSON.
Lihat panduan migrasi next-intl untuk langkah-langkah detailnya.
Kapan harus memilih yang mana?
Anda menginginkan standar ekosistem untuk Next.js, mengandalkan ICU MessageFormat, aplikasi Anda berskala kecil hingga menengah, atau Anda berintegrasi dengan platform penerjemahan (Crowdin, Phrase, Lokalise...) yang mengharapkan JSON terpusat. Alokasikan waktu untuk membagi katalog ke dalam namespace dan memilih pesan dengan pick() per halaman jika performa menjadi prioritas.
Anda menginginkan konten dengan cakupan komponen, TypeScript yang ketat, kesalahan kunci hilang pada waktu build, tree-shaking dan pemuatan lambat (lazy loading) tanpa usaha, komponen server sinkron, dan alat editorial bawaan (Editor Visual, CMS, terjemahan AI, server MCP). Sangat relevan untuk basis kode modular besar dan sistem desain.
Anda sudah menggunakan next-intl dan ingin penghematan ukuran bundel tanpa perlu menulis ulang kode. Adaptor kompatibilitas menjaga impor dan file messages/{locale}.json Anda sebagai sumber kebenaran tunggal. Diukur berdampingan dalam next-intl vs @intlayer/next-intl.
FAQ
Tidak pada waktu render. Perbedaannya terletak pada apa yang dikirim ke browser: next-intl berbiaya +12.6 KB gzip runtime pada setiap halaman dan pada konfigurasi umum mengirimkan ~90% string halaman lain bersama setiap halaman. Peralihan bahasa dan hidrasi sebanding di Next.js (15-18 ms); di TanStack Start use-intl membutuhkan 7-21 ms dibandingkan 3-4 ms untuk Intlayer.
Bisa, dengan konfigurasi scoped-dynamic: bagi messages/{locale}.json menjadi satu namespace per rute, lalu gunakan pick(messages, [...]) di setiap halaman dan jaga pemetaan tersebut tetap sinkron saat komponen berpindah. Baris scoped-* dalam tolok ukur mencerminkan pekerjaan tersebut. Intlayer mencapai 0% secara bawaan karena kompilator membatasi konten per komponen. Lihat pengoptimalan bundel.
Tidak. @intlayer/next-intl mempertahankan useTranslations, getTranslations, useFormatter, t.rich(), bentuk jamak ICU, dan helper navigasi, lalu menyediakannya dari kamus yang dikompilasi. Cukup satu baris plugin di next.config.ts. Panduan langkah demi langkah di panduan migrasi next-intl.
Dukungan ICU sedang dikembangkan pada API asli. Adaptor kompatibilitas (@intlayer/next-intl, @intlayer/use-intl) sudah menjalankan ICU: bentuk jamak, select, selectordinal, #, dan {ts, date, long} diproses melalui penyelesai ICU Intlayer. Baca format pesan ICU untuk detailnya.
Bisa. Plugin sinkronisasi JSON membacanya, membagi kunci tingkat atas menjadi kamus, dan menulis kembali terjemahan ke file yang sama ketika CLI atau CMS memperbaruinya. Alur kerja penerjemah Anda tidak berubah.
Perbandingan terkait
Tolok ukur yang sama, pustaka lain:
Mendalami next-intl:
Dokumentasi referensi:
Untuk memahami asal-usul pustaka-pustaka ini, baca sejarah i18n di JavaScript.
Bintang GitHub
Bintang GitHub adalah indikator kuat dari popularitas proyek, kepercayaan komunitas, dan prospek jangka panjang.
Aktivitas commit
Bintang menunjukkan popularitas. Commit menunjukkan seberapa banyak kerja yang masuk ke sebuah proyek. Saat tulisan ini dibuat, Intlayer memiliki sekitar 7.500 commit, lebih banyak dari sebagian besar library yang dibandingkan di sini, dan sekitar 5 kali lebih banyak dari next-intl atau next-i18next.
- amannn/next-intl
- aymericzip/intlayer
Commit pada branch default, sumber: GitHub API.
Intlayer adalah monorepo, jadi jumlah ini mencakup setiap paket framework, CLI, dan dokumentasi. Baca commit sebagai sinyal aktivitas, bukan kualitas.
Unduhan npm
- next-intl
- next-intlayer
Sumber: API unduhan registri npm.
Jumlah unduhan menghargai solusi yang paling lama, bukan yang terbaik. Library yang dirilis bertahun-tahun lalu masih diinstal oleh setiap proyek yang memilihnya saat itu, oleh setiap eksekusi CI, dan oleh setiap paket yang bergantung padanya. Angka ini lebih mengukur inersia daripada pilihan baru.
Asisten AI memperkuat efek ini. next-intl, i18next, dan vue-i18n ada di mana-mana dalam kode yang menjadi data latih mereka, sehingga mereka menyarankannya secara default tanpa membandingkan alternatif. Setiap saran menambah unduhan, yang kemudian mendorong saran berikutnya. Bandingkan berdasarkan benchmark, bukan jumlah unduhan.
Kesimpulan
next-intl adalah pustaka yang solid dan dirawat dengan baik, dan pengujian mengonfirmasi bahwa pustaka ini merupakan pilihan yang baik di Next.js. Namun model katalog terpusat membebankan setiap optimasi kepada pengembang: pengaturan sederhana membocorkan sekitar 90% konten halaman lain, dan runtime-nya sendiri berbiaya +12.6 KB gzip pada setiap halaman.
Intlayer memindahkan semua pekerjaan itu ke kompiler. Kamus per komponen, lazy loading per lokal, dan pembersihan konten yang tidak terpakai adalah output build otomatis. Hasilnya pada aplikasi yang sama: +0.3 KB per halaman, 0% kebocoran, komponen 3x lebih kecil, dan pergantian lokal 2x-4x lebih cepat pada TanStack Start.
Semua data mentah, aplikasi pengujian, dan skrip tersedia di repositori Benchmark Bloom. Anda dapat menjalankannya sendiri.
Lihat dokumen 'Mengapa Intlayer?' untuk detail lebih lanjut.
Komentar
Belum ada komentar. Jadilah yang pertama membagikan pemikiran Anda.
