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
i18next VS @intlayer/i18next: API yang Sama, Bundle Berbeda

@intlayer/i18next, @intlayer/react-i18next, dan @intlayer/next-i18next adalah adapter kompatibilitas. Mereka mengekspos API i18next yang sudah digunakan kode Anda (useTranslation, t(), <Trans>, i18n.changeLanguage(), getFixedT, serverSideTranslations...) dan menyajikannya dari kamus (dictionaries) yang dikompilasi oleh Intlayer. Komponen tidak berubah. Runtime di bawahnya yang berubah.
Artikel ini mengukur pertukaran tersebut pada aplikasi Next.js yang sama, dibangun sekali dengan next-i18next dan sekali dengan @intlayer/next-i18next. Angka-angka ini berasal dari Benchmark Bloom. Untuk perbandingan i18next dan Intlayer sebagai library, baca i18next vs Intlayer. Artikel ini berfokus pada apa yang diubah oleh adapter saat Anda mempertahankan kode apa adanya.
tl;dr: Pada aplikasi Next.js yang sama, menggantinext-i18nextdengan@intlayer/next-i18nextmemangkas JavaScript per halaman dari 218.5 KB menjadi 150.7 KB gzip (setup naif) dan mengalahkan setupnext-i18nextyang dioptimalkan sepenuhnya (163.4 KB) sebesar 12.7 KB. Rata-rata ukuran komponen turun dari 78.5 KB menjadi 9.7 KB, kebocoran string halaman lain turun dari ~90% menjadi 0%, hidrasi dari 15.6 ms menjadi 11.3 ms, dan runtime dari 19.7 KB menjadi 9.4 KB. Tidak ada komponen yang diedit; hanya satu file provider yang diubah. Plugini18next(backend, detektor bahasa) diterima tetapi tidak melakukan apa pun: tidak ada lagi yang perlu dimuat atau dideteksi saat runtime.
Apa itu @intlayer/i18next
i18next adalah sebuah runtime. i18n.init({ resources }) atau plugin backend memuat locales/{lng}/{ns}.json ke dalam instance global; useTranslation("about") mendaftarkan komponen ke dalamnya; t("title") mencari kunci pada saat render. Namespace, lazy loading, daftar namespace per halaman, dan keamanan tipe data (type safety) semuanya harus Anda konfigurasikan dan kelola sendiri.
Adapter mempertahankan API dan mengganti instance:
- Import aliasing.
createNextI18nPlugin()dari@intlayer/next-i18next/plugin(atauwithI18next) membungkuswithIntlayerdan menambahkan alias Webpack / Turbopack sehingganext-i18next,react-i18next, dani18nextmengarah ke padanan@intlayer/*mereka. Pada Vite,reactI18nextVitePlugin()dari@intlayer/react-i18next/pluginmelakukan hal yang sama. Tidak ada import yang diganti namanya. - JSON sebagai sumber kebenaran (source of truth). Plugin
syncJSONmembaca filelocales/{lng}/{ns}.jsonAnda yang ada denganformat: "i18next"(sehingga{{name}}, penumpukan$t(), sufiks_one/_other, dan konteks diparsing dengan benar) dan menulis kembali terjemahan saat CLI atau CMS memperbaruinya. - Pengikatan titik panggilan (call-site binding). Tahap optimasi Intlayer menulis ulang
useTranslation("about")menjadi panggilan yang menerima kamusaboutsecara langsung, dalam locale yang aktif. Komponen tidak lagi mengakses store global.
Salin kode ke clipboard
Salin kode ke clipboard
Penulisan ulang itulah yang mengubah angka pada kolom ukuran komponen dan kebocoran halaman di bawah ini.
Apa yang dipertahankan, diabaikan, dan tidak digantikan oleh adapter
Buka tabel dalam modal untuk melihat semua isi data dengan jelas
API i18next | Dengan @intlayer/* |
|---|---|
useTranslation("ns"), useTranslation("ns", { keyPrefix }) | ✅ Dipertahankan. Terikat ke kamus ns saat build; kunci bertipe sesuai konten Anda |
t("key", { name }), {{interpolation}}, penumpukan $t(key) | ✅ Dipertahankan |
Jamak key_one / key_other, konteks key_male, returnObjects | ✅ Dipertahankan. Jamak dievaluasi dengan Intl.PluralRules |
<Trans> dengan components, tag bernomor <1>...</1>, values | ✅ Dipertahankan |
withTranslation, Translation, I18nContext | ✅ Dipertahankan |
i18n.changeLanguage(), i18n.language, i18n.dir(), on("languageChanged") | ✅ Dipertahankan. changeLanguage mengontrol locale Intlayer |
getFixedT(lng, ns, keyPrefix), i18n.exists(), hasLoadedNamespace() | ✅ Dipertahankan |
i18n.use(Backend).use(LanguageDetector).init({...}) | ⚠️ use() memanggil init plugin dan mengembalikan; backend dan detektor tidak memiliki apa pun untuk dimuat atau dideteksi |
init({ resources }), addResourceBundle() | ⚠️ resources diabaikan dengan peringatan dev; hapus import JSON untuk mendapatkan penghematan bundle |
I18nextProvider i18n={i18n} | ⚠️ Merender IntlayerProvider; prop i18n diabaikan. Di App Router, berikan locale (lihat di bawah) |
serverSideTranslations(locale, ["common"]) (next-i18next) | ⚠️ Mengembalikan bentuk yang diharapkan dan tidak memuat apa pun. Aman dipertahankan, aman dihapus |
appWithTranslation(App) (next-i18next) | ✅ Dipertahankan |
next-i18next.config.js | ⚠️ Tidak dibaca. Locale berasal dari intlayer.config.ts |
useTranslation() polos tanpa namespace | ✅ Bekerja terhadap kamus translation seluruh file (splitKeys: false) |
Benchmark
Apa yang diukur
Suite Benchmark Bloom membangun aplikasi yang sama persis dengan masing-masing konfigurasi: 10 halaman (home, about, blog, careers, contact, FAQ, pricing, products, settings, team), 10 locale (en, fr, es, de, it, pt, zh, ja, ko, ru), komponen identik, dan konten identik. Halaman diukur dalam en dan fr.
next-i18next dibangun dalam empat strategi pemuatan, mulai dari JSON setiap locale diimpor ke resources (static) hingga satu namespace per rute yang dimuat secara malas melalui backend (scoped-dynamic). Adapter dibangun pada komponen yang sama dengan setup naif, dengan perubahan pada next.config.ts, intlayer.config.ts, dan file provider. Adapter tidak memiliki varian "scoped": kompilator membatasi cakupan konten per komponen secara otomatis.
Untuk setiap build, suite mencatat:
- Lib size: ukuran gzip komponen kosong yang hanya mengimpor library i18n.
- Page JS: JavaScript gzip yang diunduh per halaman, dirata-ratakan di semua halaman dan locale.
- Locale leak %: proporsi string terjemahan dalam JS yang diunduh yang termasuk dalam locale yang tidak sedang dilihat pengguna.
- Page leak %: proporsi string terjemahan dalam JS yang diunduh yang termasuk dalam halaman tempat pengguna tidak berada.
- Component avg: rata-rata ukuran gzip setiap komponen yang dikompilasi secara terisolasi.
- E2E reactivity: waktu nyata antara pemilihan locale baru dan pembaruan
html[lang]di DOM (Playwright, 5 iterasi). - Hydration: durasi fase hidrasi React.
Angka di bawah ini berasal dari pengujian tanggal 2026-09-12 dengannext-i18next16.3.0 (react-i18next17.0.13,i18next26.4.2) dan@intlayer/next-i18next9.5.1. Aplikasi uji sengaja dibuat kecil (beberapa puluh string per locale), sehingga persentase kebocoran menggambarkan pola: mereka tumbuh bersama konten Anda sementara biaya runtime tetap konstan.
Hasil pada Next.js
Pilih metrik dan pustaka yang Anda minati:
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
| Setup | Strategi | Lib size (gz) | Page JS avg (gz) | Locale leak | Page leak | Component avg (gz) | E2E reactivity | Hydration |
|---|---|---|---|---|---|---|---|---|
| base (tanpa i18n) | - | 0.0 KB | 141.0 KB | 0.0% | 0.0% | 0.9 KB | 13.4 ms | 11.8 ms |
next-i18next | static | 19.7 KB | 218.5 KB | 0.0% | 89.8% | 78.5 KB | 16.4 ms | 15.6 ms |
next-i18next | dynamic | 19.7 KB | 169.5 KB | 50.0% | 89.8% | 26.1 KB | 15.4 ms | 27.7 ms |
next-i18next | scoped-static | 19.7 KB | 220.1 KB | 0.0% | 89.8% | 78.9 KB | 16.4 ms | 14.7 ms |
next-i18next | scoped-dynamic | 19.7 KB | 163.4 KB | 0.0% | 0.0% | 27.1 KB | 15.9 ms | 15.1 ms |
@intlayer/next-i18next | static | 9.4 KB | 150.7 KB | 0.0% | 0.0% | 9.7 KB | 10.7 ms | 11.3 ms |
@intlayer/next-i18next | dynamic | 9.4 KB | 150.7 KB | 0.0% | 0.0% | 9.7 KB | 11.9 ms | 10.6 ms |
next-intlayer (native) | static | 5.5 KB | 141.3 KB | 0.0% | 0.0% | 8.5 KB | 15.5 ms | 16.9 ms |
next-intlayer (native) | dynamic | 5.5 KB | 141.3 KB | 0.0% | 0.0% | 6.9 KB | 15.3 ms | 15.9 ms |
Cara membaca data
- Hemat 68 KB per halaman dibandingkan setup naif.
resources: { en, fr, ... }menyertakan setiap locale dan setiap namespace di setiap halaman: 218.5 KB. Build adapter dari komponen yang sama menghasilkan 150.7 KB. Ini juga mengalahkan konfigurasi terbaiknext-i18next(163.4 KB, satu namespace per rute, dimuat secara malas) sebesar 12.7 KB, karena runtimei18nextsaja berbobot 19.7 KB dibandingkan 9.4 KB. - Kebocoran turun menjadi 0% tanpa menyentuh satu pun komponen. Setiap setup
next-i18nextkecuali yang sepenuhnya terisolasi (scoped) menyertakan ~90% string halaman lain. Barisdynamicbahkan lebih buruk daripada kelihatannya: tidak menurunkan kebocoran halaman sama sekali dan justru menambah 50% kebocoran locale, karena backend per locale tetap memuat seluruh namespacetranslation. Adapter mencapai 0% / 0% langsung dari kode naif. - Komponen: 8x lebih kecil. Komponen
useTranslation()yang dikompilasi secara terisolasi berukuran rata-rata 78.5 KB denganresourcesinline dan 26-27 KB dengan backend, karenatterikat ke global store. Dengan adapter, ukurannya rata-rata hanya 9.7 KB. - Hidrasi dan pergantian bahasa lebih cepat. Hidrasi meningkat dari 15.6 ms menjadi 11.3 ms (dan dari 27.7 ms pada setup
dynamic, di mana pengambilan data dari backend berada di jalur kritis). Pergantian locale meningkat dari 15-16 ms menjadi 11-12 ms. - Adapter bukanlah runtime native.
next-intlayerberukuran 141.3 KB, hanya +0.3 KB di atas aplikasi dasar. Adapter membawa permukaan APIi18next(dialek interpolasi, resolusi sufiks jamak dan konteks, penguraian tag<Trans>) di atas inti Intlayer: 9.4 KB dan +9.4 KB per halaman dibandingkan native. Ini adalah jembatan transisi, bukan tujuan akhir.
Tabel lengkap, setiap pustaka dan strategi, dalam laporan benchmark Next.js.
Hasil di TanStack Start (react-i18next)
Untuk Vite dan TanStack Start, benchmark membandingkan react-i18next murni dengan intlayer:
Buka tabel dalam modal untuk melihat semua isi data dengan jelas
| Library | Strategi | Lib size (gz) | Page JS avg (gz) | Locale leak | Page leak | Component avg (gz) | E2E reactivity | Hydration |
|---|---|---|---|---|---|---|---|---|
| base (tanpa i18n) | - | 0.0 KB | 111.0 KB | 0.0% | 0.0% | 0.7 KB | 8.1 ms | 21.6 ms |
react-i18next | dynamic | 18.4 KB | 136.4 KB | 23.1% | 89.8% | 24.8 KB | 123.1 ms | 32.9 ms |
intlayer | dynamic | 5.0 KB | 118.6 KB | 0.0% | 0.0% | 6.3 KB | 3.6 ms | 14.1 ms |
Tabel lengkap dalam laporan benchmark TanStack Start.
Adapterreact-i18nextpada Vite / TanStack Start tidak diikutsertakan dalam pengujian ini. Data dasarreact-i18nextpada TanStack Start ada di i18next vs Intlayer: 127-184 KB per halaman dan pergantian locale 123-185 ms saat backend dimuat secara malas.
Mengapa angkanya berubah

Tidak ada apa pun di direktori components/ yang diubah, sehingga penghematan berasal dari apa yang diikat oleh useTranslation.
Dengan i18next, pengikatan dilakukan ke instance global. Apa pun yang dimuat ke dalamnya (semua locale dalam static, seluruh namespace locale aktif dalam dynamic) dapat diakses dari setiap komponen yang memanggil useTranslation(). Bundler tidak dapat memecah di bawah apa yang dimuat oleh instance tersebut, dan runtime tidak dapat mengetahui kunci mana yang akan diminta komponen.
Salin kode ke clipboard
Apa pun yang ditampung instans dikirim ke setiap halaman, dan pemborosan bertambah pada dua sumbu, halaman dan lokal:

Dengan @intlayer/next-i18next, pengikatan dilakukan ke kamus. syncJSON mengubah setiap file namespace menjadi kamus; tahap optimasi memberikan kamus yang dibutuhkan langsung ke komponen, sebagai modul import yang dapat dilacak dan dipecah oleh bundler per halaman dan per locale.
Salin kode ke clipboard
i18n/i18n.ts dan import resources-nya menjadi dead code. Itulah sumber penghematan 68 KB tersebut.
Migrasi dalam tiga langkah
Instalasi
bashSalin kodeSalin kode ke clipboard
Perintah ini mendeteksi
i18next/react-i18next/next-i18next, menginstalintlayer, paket framework (next-intlayerataureact-intlayer), adapter@intlayer/*yang sesuai, dan@intlayer/sync-json-plugin, serta mengisiintlayer.config.ts. Pertahankan paket asli tetap terinstal: mereka adalah peer dependencies dan menyediakan tipe data TypeScript.Arahkan Intlayer ke file locale Anda
intlayer.config.tsSalin kodeSalin kode ke clipboard
Jika Anda memiliki satu
translation.jsonper locale (namespace bawaan i18next), atursplitKeys: falseagar seluruh file tetap menjadi satu kamus danuseTranslation()tanpa argumen tetap berfungsi.Tambahkan plugin
next.config.tsSalin kodeSalin kode ke clipboard
Pada App Router, komponen klien mendapatkan locale dari segmen
[locale]. KomponenI18nextProvideradapter tidak menerima parameter locale, jadi ganti sekali di file provider Anda:components/AppProviders.tsxSalin kodeSalin kode ke clipboard
Setiap komponen di bawahnya tetap memanggil
useTranslation().vite.config.tsSalin kodeSalin kode ke clipboard
reactI18nextVitePlugin()membungkusvite-intlayerdan membuat alias untukreact-i18nextdani18next. Untuk proyek non-React,i18nextVitePlugin()dari@intlayer/i18next/pluginmembuat alias untuki18nextsaja.
Apa yang dapat Anda hapus setelahnya
Buka tabel dalam modal untuk melihat semua isi data dengan jelas
| File / pola | Alasan |
|---|---|
resources: { en, fr, ... } dan import JSON | Diabaikan oleh adapter. Di sinilah letak 68 KB yang dihemat |
i18next-http-backend, i18next-resources-to-backend | Tidak ada yang perlu diambil saat runtime |
i18next-browser-languagedetector | Deteksi locale ditangani konfigurasi routing Intlayer (awalan URL, cookie, header) |
serverSideTranslations() di getStaticProps | Mengembalikan bentuk kosong; tidak berbahaya, tetapi tidak lagi diperlukan |
next-i18next.config.js | Tidak dibaca. Konfigurasi locale berada di intlayer.config.ts |
Daftar ns: [...] per halaman | Kompilator memilih namespace per komponen |
Apa yang Anda dapatkan selain penghematan byte
- Kunci bertipe data aman (typed keys).
useTranslation("about")memiliki tipe terhadap kamusaboutyang dikompilasi;t("does.not.exist")menjadi error TypeScript, bukan mengembalikan string kunci biasa. npx intlayer testmenggagalkan CI jika ada kunci yang hilang di locale mana pun.npx intlayer fillmenerjemahkan kunci yang hilang menggunakan kunci API penyedia AI Anda sendiri (OpenAI, Anthropic, Mistral, Gemini...) dan menyimpannya kembali kelocales/{lng}/{ns}.json.- Visual Editor dan CMS beroperasi pada JSON yang sama, sehingga penerjemah dapat mengedit melalui antarmuka visual dan file diperbarui.
- Transisi bertahap ke
.content.ts. Komponen mana pun dapat beralih dariuseTranslation("about")keuseIntlayer("about")dengan file konten yang diletakkan bersama komponen. Kamus JSON dan.content.tsdapat hidup berdampingan.
Batasan yang perlu diketahui sebelum memulai
i18n.use(HttpBackend) memanggil init plugin dan tidak melakukan hal lain. Jika aplikasi Anda mengandalkan pengambilan terjemahan dari CMS saat runtime, alur tersebut tidak ada lagi; gunakan CMS Intlayer atau perintah intlayer pull / push. Deteksi bahasa menjadi konfigurasi perutean Intlayer (prefiks URL, cookie, header).
Tidak seperti beberapa adaptor lainnya, @intlayer/i18next tidak menggunakan resources inline sebagai fallback. Setiap kunci harus ada dalam kamus yang disinkronkan, yang diverifikasi oleh intlayer test.
Hanya satu berkas, ditunjukkan di atas. Pages Router dengan appWithTranslation tidak memerlukan apa pun.
localePath, fallbackLng, reloadOnPrerender dan sejenisnya tidak memiliki padanan; bahasa dan fallback berasal dari intlayer.config.ts.
9.4 KB runtime dan +9.4 KB per halaman dibandingkan next-intlayer. Setelah setiap komponen beralih ke useIntlayer, hapus adaptor tersebut.
Perbandingan fitur
Di luar ukuran byte, inilah yang diberikan setiap opsi:
Buka tabel dalam modal untuk melihat semua isi data dengan jelas
| Fitur | i18next / react-i18next / next-i18next | Adapter @intlayer/* | Intlayer native |
|---|---|---|---|
Panggilan t(), useTranslation, <Trans> Anda | ✅ | ✅ Tidak berubah | ❌ Dipindahkan ke useIntlayer |
| Ukuran runtime (gzip, Next.js) | 19.7 KB | 9.4 KB | 5.5 KB |
| Kebocoran halaman lain tanpa namespace manual | ~90% | 0% | 0% |
| Key bertipe | ⚠️ Deklarasi manual | ✅ Dari kamus yang dikompilasi | ✅ Dibuat otomatis |
| Backend dan plugin runtime | ✅ Ekosistem plugin lengkap | ❌ Tidak aktif | ❌ Tidak berlaku, gunakan CMS |
| Konten berdampingan dengan komponen | ❌ JSON terpusat | ⚠️ JSON, .content.ts dapat berdampingan | ✅ .content.ts di samping setiap komponen |
| Terjemahan yang hilang di CI | ⚠️ Tidak bawaan | ✅ npx intlayer test | ✅ npx intlayer test |
| Terjemahan AI | ❌ Tidak | ✅ npx intlayer fill | ✅ npx intlayer fill |
| Editor visual / CMS | ❌ Melalui platform eksternal | ✅ Pada JSON yang sama | ✅ Ya |
| Ekosistem / komunitas | ✅ Sangat besar | ⚠️ Lebih kecil, tumbuh cepat | ⚠️ Lebih kecil, tumbuh cepat |
Ukuran runtime berasal dari pengujian Next.js yang dijelaskan di atas.
Kapan menggunakan yang mana?
Aplikasi Anda bergantung pada backend runtime (terjemahan yang disajikan oleh CMS pada saat permintaan), pada ekosistem plugin, atau pada target non-React yang tidak dicakup oleh adaptor.
Anda menggunakan react-i18next / next-i18next dan menginginkan penghematan 68 KB, komponen 8x lebih kecil, 0% kebocoran, kunci bertipe, dan pemeriksaan CI tanpa penulisan ulang. Ini adalah titik masuk untuk basis kode i18next yang sudah ada.
Untuk proyek baru, atau setelah adaptor menyelesaikan tugasnya. Menawarkan runtime teringan (5.5 KB, +0.3 KB per halaman) dan membuka Server Components sinkron serta berkas .content.ts per komponen. Mulai dengan Intlayer dengan Next.js atau dengan Vite dan React.
FAQ
Dari resources: { en, fr, ... }. Penyiapan umum next-i18next mengimpor JSON setiap bahasa ke init(), sehingga setiap halaman membawa setiap namespace di setiap bahasa: 218.5 KB per halaman. Adaptor tidak pernah membundel blok itu; adaptor hanya memberikan kamus yang disebutkan ke setiap komponen, dalam bahasa yang aktif.
Ya, dengan components, tag bernomor <1>...</1> dan values. Begitu pula dengan {{interpolation}}, penyarangan $t(key), bentuk jamak key_one / key_other (dievaluasi dengan Intl.PluralRules), sufiks konteks, dan returnObjects.
Atur splitKeys: false di plugin syncJSON. Seluruh berkas tetap menjadi satu kamus dan panggilan sederhana useTranslation() akan terus menyelesaikan terhadapnya.
Tidak, ini adalah jembatan. Adaptor mempertahankan API i18next dan berbiaya runtime 9.4 KB; next-intlayer native berbiaya 5.5 KB dan menambahkan Server Components sinkron serta berkas .content.ts yang ditempatkan bersama. Anda dapat bermigrasi komponen demi komponen, karena kamus JSON dan .content.ts hidup berdampingan.
Ya. locales/{lng}/{ns}.json tetap menjadi sumber kebenaran: syncJSON membacanya dengan dialek i18next dan menulis kembali terjemahan saat CLI atau CMS memperbaruinya.
Perbandingan terkait
Seri adaptor yang sama:
Pustaka yang dibandingkan secara langsung:
Dokumentasi referensi:
Compat adapters:
Migration guides:
Untuk memahami asal-usul pustaka-pustaka ini, baca sejarah i18n di JavaScript.
Kesimpulan
i18next adalah runtime terberat dalam benchmark ini, dan adapter ini memangkas sebagian besar bebannya tanpa mengharuskan Anda meninggalkan API yang sudah dikenal. Pada aplikasi Next.js yang sama, Anda memperoleh pengurangan 68 KB per halaman dibandingkan setup naif, 12.7 KB lebih hemat daripada konfigurasi paling optimal secara manual, komponen 8x lebih kecil, 0% kebocoran, dan hidrasi 4 ms lebih cepat, hanya dengan satu file konfigurasi, satu baris plugin, dan satu penyesuaian provider. Backend dan detektor menjadi no-op, resources diabaikan daripada digabungkan, dan runtime native next-intlayer tetap lebih ringan 9 KB lagi.
Semua data mentah, aplikasi pengujian, dan skrip tersedia di repositori Benchmark Bloom. Jalankan dan buktikan sendiri.
Lihat dokumentasi 'Mengapa Intlayer?' untuk detail selengkapnya.
Komentar
Belum ada komentar. Jadilah yang pertama membagikan pemikiran Anda.
