Ajukan pertanyaan Anda dan dapatkan ringkasan dokumen dengan merujuk halaman ini dan penyedia AI pilihan Anda
Riwayat Versi
- "Menambahkan opsi splitKeys (satu kamus per kunci namespace tingkat atas) untuk tata letak file tunggal next-intl / react-intl"v9.0.021/6/2026
- "Menambahkan dukungan format ICU dan i18next"v7.5.013/12/2025
- "Dokumentasi awal plugin Sinkronisasi JSON"v6.1.65/10/2025
Konten halaman ini diterjemahkan menggunakan AI.
Lihat versi terakhir dari konten aslinya dalam bahasa InggrisIf you have an idea for improving this documentation, please feel free to contribute by submitting a pull request on GitHub.
GitHub link to the documentationCopy doc Markdown to clipboard
Sinkronisasi JSON (jembatan i18n) - Sinkronisasi JSON dengan dukungan ICU / i18next
Gunakan Intlayer sebagai tambahan pada tumpukan i18n Anda yang sudah ada. Plugin ini menjaga pesan JSON Anda tetap sinkron dengan kamus Intlayer sehingga Anda dapat:
- Mempertahankan i18next, next-intl, react-intl, vue-i18n, next-translate, nuxt-i18n, Solid-i18next, svelte-i18n, dll.
- Mengelola dan menerjemahkan pesan Anda dengan Intlayer (CLI, CI, penyedia, CMS), tanpa perlu merombak aplikasi Anda.
- Mengirimkan tutorial dan konten SEO yang menargetkan setiap ekosistem, sambil menyarankan Intlayer sebagai lapisan pengelolaan JSON.
Catatan dan cakupan saat ini:
- Eksternalisasi ke CMS berfungsi untuk terjemahan dan teks klasik.
- Belum mendukung penyisipan, bentuk jamak/ICU, atau fitur runtime lanjutan dari pustaka lain.
- Editor visual belum didukung untuk output i18n pihak ketiga.
Kapan menggunakan plugin ini
- Anda sudah menggunakan perpustakaan i18n dan menyimpan pesan dalam file JSON.
- Anda menginginkan pengisian berbantuan AI, pengujian di CI, dan operasi konten tanpa mengubah runtime rendering Anda.
Instalasi
Salin kode ke clipboard
pnpm add -D @intlayer/sync-json-plugin# ataunpm i -D @intlayer/sync-json-pluginPlugins
This package provides two plugins:
loadJSON: Load JSON files into Intlayer dictionaries.- This plugin is used to load JSON files from a source and will be loaded into Intlayer dictionaries. It can scan all the codebase and search for specific JSON files.
This plugin can be used
- if you use an i18n library that impose a specific location for your JSON to be loaded (ex:
next-intl,i18next,react-intl,vue-i18n, etc.), but you want to place your content declaration where you want in your code base. - It can also be used if you want to fetch your messages from a remote source (ex: a CMS, a API, etc.) and store your messages in JSON files.
- if you use an i18n library that impose a specific location for your JSON to be loaded (ex:
Under the hood, this plugin will scan all the codebase and search for specific JSON files and load them into Intlayer dictionaries. Note that this plugin will not write the output and translations back to the JSON files.
- This plugin is used to load JSON files from a source and will be loaded into Intlayer dictionaries. It can scan all the codebase and search for specific JSON files.
This plugin can be used
syncJSON: Synchronize JSON files with Intlayer dictionaries.- This plugin is used to synchronize JSON files with Intlayer dictionaries. It can scan the given location and load the JSON that match the pattern for specific JSON files. This plugin is useful if you want to get the benefits of Intlayer while using another i18n library.
Using both plugins
Salin kode ke clipboard
import { Locales, type IntlayerConfig } from "intlayer";import { loadJSON, syncJSON } from "@intlayer/sync-json-plugin";const config: IntlayerConfig = { internationalization: { locales: [Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH], defaultLocale: Locales.ENGLISH, }, // Keep your current JSON files in sync with Intlayer dictionaries plugins: [ /** * Will load all the JSON files in the src that match the pattern {key}.i18n json */ loadJSON({ source: ({ key }) => `./src/**/${key}.i18n.json`, locale: Locales.ENGLISH, priority: 1, // Ensures these JSON files take precedence over files at `./locales/en/${key}.json` format: "intlayer", // Format of the JSON content }), /** * Will load, and write the output and translations back to the JSON files in the locales directory */ syncJSON({ source: ({ key, locale }) => `./locales/${locale}/${key}.json`, priority: 0, format: "i18next", }), ],};export default config;syncJSON plugin
Quick start
Tambahkan plugin ke intlayer.config.ts Anda dan arahkan ke struktur JSON yang sudah ada.
Salin kode ke clipboard
import { Locales, type IntlayerConfig } from "intlayer";import { syncJSON } from "@intlayer/sync-json-plugin";const config: IntlayerConfig = { internationalization: { locales: [Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH], defaultLocale: Locales.ENGLISH, }, // Jaga file JSON Anda saat ini tetap sinkron dengan kamus Intlayer plugins: [ syncJSON({ // Tata letak per-locale, per-namespace (misalnya, next-intl, i18next dengan namespaces) source: ({ key, locale }) => `./locales/${locale}/${key}.json`, format: "icu", }), ],};export default config;Alternatif: satu file per locale (umum dengan pengaturan i18next/react-intl):
Salin kode ke clipboard
import { Locales, type IntlayerConfig } from "intlayer";import { syncJSON } from "@intlayer/sync-json-plugin";const config: IntlayerConfig = { internationalization: { locales: [Locales.ENGLISH, Locales.FRENCH], defaultLocale: Locales.ENGLISH, }, plugins: [ syncJSON({ format: "i18next", source: ({ locale }) => `./locales/${locale}.json`, format: "i18next", }), ],};export default config;Cara kerjanya
- Baca: plugin menemukan file JSON dari pembangun
sourceAnda dan memuatnya sebagai kamus Intlayer. - Tulis: setelah proses build dan pengisian, plugin menulis kembali JSON yang sudah dilokalkan ke jalur yang sama (dengan newline akhir untuk menghindari masalah format).
- Auto‑fill: plugin mendeklarasikan jalur
autoFilluntuk setiap kamus. Menjalankanintlayer fillsecara default hanya memperbarui terjemahan yang hilang dalam file JSON Anda.
API:
Salin kode ke clipboard
syncJSON({ source: ({ key, locale }) => string, // wajib location?: string, // label opsional, default: "plugin" priority?: number, // prioritas opsional untuk resolusi konflik, default: 0 format?: 'intlayer' | 'icu' | 'i18next', // formatter opsional, digunakan untuk kompatibilitas runtime Intlayer splitKeys?: boolean, // opsional, membagi satu file menjadi satu kamus per kunci tingkat atas (terdeteksi otomatis)});format ('intlayer' | 'icu' | 'i18next')
Menentukan formatter yang akan digunakan untuk konten kamus saat menyinkronkan file JSON. Ini memungkinkan penggunaan berbagai sintaks pemformatan pesan yang kompatibel dengan runtime Intlayer.
undefined: Tidak ada formatter yang akan digunakan, konten JSON akan digunakan apa adanya.'intlayer': Formatter Intlayer default (default).'icu': Menggunakan pemformatan pesan ICU (kompatibel dengan pustaka seperti react-intl, vue-i18n).'i18next': Menggunakan pemformatan pesan i18next (kompatibel dengan i18next, next-i18next, Solid-i18next).
Perhatikan bahwa menggunakan formatter akan mengubah konten JSON Anda pada input dan output. Untuk aturan JSON yang kompleks seperti pluralisasi ICU, parsing mungkin tidak menjamin pemetaan 1 ke 1 antara input dan output. Jika Anda tidak menggunakan runtime Intlayer, Anda mungkin lebih memilih untuk tidak mengatur formatter.
Contoh:
Salin kode ke clipboard
syncJSON({ source: ({ key, locale }) => `./locales/${locale}/${key}.json`, format: "i18next", // Gunakan pemformatan i18next untuk kompatibilitas}),splitKeys (boolean)
Mengontrol apakah satu file JSON yang kunci tingkat pertamanya adalah namespace harus menjadi satu kamus per kunci tingkat atas, alih-alih satu kamus yang menampung seluruh file.
Ini cocok dengan model namespace dari pustaka seperti next-intl dan react-intl, di mana satu file messages/{locale}.json mengelompokkan beberapa namespace berdasarkan kunci tingkat pertamanya, masing-masing ditangani secara independen (misalnya useTranslations('Hero') menyelesaikan ke kamus Hero).
undefined(default): terdeteksi otomatis — file dibagi ketika polasourcetidak memiliki segmen{key}(satu file menampung setiap namespace), dan disimpan sebagai satu kamus jika tidak (satu file per kunci).true: selalu membagi setiap kunci tingkat atas menjadi kamusnya sendiri.false: jangan pernah membagi; seluruh file menjadi satu kamus.
Mengingat satu file messages/{locale}.json:
Salin kode ke clipboard
{ "Hero": { "title": "Full-stack developer" }, "Nav": { "work": "Work", "about": "About" }, "About": { "lead": "I build apps end to end." }}Salin kode ke clipboard
syncJSON({ format: "icu", source: ({ locale }) => `./messages/${locale}.json`, // splitKeys: true, // tersirat karena pola tidak memiliki segmen `{key}`}),Ini menghasilkan tiga kamus — Hero, Nav, dan About — sehingga useTranslations('Hero') (next-intl) menyelesaikan dengan benar. Saat ditulis kembali, semua namespace disatukan kembali ke dalam file per-locale yang sama.
Ketika Anda mempertahankan segmen{key}eksplisit disourceAnda (misalnya./locales/${locale}/${key}.json), setiap file sudah menjadi satu namespace, sehingga pemisahan dinonaktifkan secara default.
Multiple JSON sources and priority
Anda dapat menambahkan beberapa plugin syncJSON untuk menyinkronkan berbagai sumber JSON. Ini berguna ketika Anda memiliki beberapa pustaka i18n atau struktur JSON yang berbeda dalam proyek Anda.
Sistem prioritas
Ketika beberapa plugin menargetkan kunci kamus yang sama, parameter priority menentukan plugin mana yang diutamakan:
- Angka prioritas yang lebih tinggi menang atas yang lebih rendah
- Prioritas default untuk file
.contentadalah0 - Prioritas default untuk file konten plugin adalah
0 - Plugin dengan prioritas yang sama diproses sesuai urutan kemunculannya dalam konfigurasi
Salin kode ke clipboard
import { Locales, type IntlayerConfig } from "intlayer";import { syncJSON } from "@intlayer/sync-json-plugin";const config: IntlayerConfig = { internationalization: { locales: [Locales.ENGLISH, Locales.FRENCH], defaultLocale: Locales.ENGLISH, }, plugins: [ // Sumber JSON utama (prioritas tertinggi) syncJSON({ format: "i18next", source: ({ key, locale }) => `./locales/${locale}/${key}.json`, location: "main-translations", priority: 10, }), // Sumber JSON cadangan (prioritas lebih rendah) syncJSON({ format: "i18next", source: ({ locale }) => `./fallback-locales/${locale}.json`, location: "fallback-translations", priority: 5, }), // Sumber JSON Legacy (prioritas terendah) syncJSON({ format: "i18next", source: ({ locale }) => `/my/other/app/legacy/${locale}/messages.json`, location: "legacy-translations", priority: 1, }), ],};export default config;Load JSON plugin
Quick start
Add the plugin to your intlayer.config.ts to ingest existing JSON files as Intlayer dictionaries. This plugin is read‑only (no writes to disk):
Salin kode ke clipboard
import { Locales, type IntlayerConfig } from "intlayer";import { loadJSON } from "@intlayer/sync-json-plugin";const config: IntlayerConfig = { internationalization: { locales: [Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH], defaultLocale: Locales.ENGLISH, }, plugins: [ // Ingest JSON messages located anywhere in your source tree loadJSON({ source: ({ key }) => `./src/**/${key}.i18n.json`, // Load a single locale per plugin instance (defaults to the config defaultLocale) locale: Locales.ENGLISH, priority: 0, }), ],};export default config;Alternative: per‑locale layout, still read‑only (only the selected locale is loaded):
Salin kode ke clipboard
import { Locales, type IntlayerConfig } from "intlayer";import { loadJSON } from "@intlayer/sync-json-plugin";const config: IntlayerConfig = { internationalization: { locales: [Locales.ENGLISH, Locales.FRENCH], defaultLocale: Locales.ENGLISH, }, plugins: [ loadJSON({ // Only files for Locales.FRENCH will be loaded from this pattern source: ({ key, locale }) => `./locales/${locale}/${key}.json`, locale: Locales.FRENCH, }), ],};export default config;How it works
- Discover: builds a glob from your
sourcebuilder and collects matching JSON files. - Ingest: loads each JSON file as an Intlayer dictionary with the provided
locale. - Read‑only: does not write or format output files; use
syncJSONif you need round‑trip sync. - Auto‑fill ready: defines a
fillpattern sointlayer content fillcan populate missing keys.
API
Salin kode ke clipboard
loadJSON({ // Bangun jalur ke JSON Anda. `locale` bersifat opsional jika struktur Anda tidak memiliki segmen locale source: ({ key, locale }) => string, // Locale target untuk kamus yang dimuat oleh instance plugin ini // Default ke configuration.internationalization.defaultLocale locale?: Locale, // Label opsional untuk mengidentifikasi sumber location?: string, // default: "plugin" // Prioritas yang digunakan untuk resolusi konflik terhadap sumber lain priority?: number, // default: 0 // Formatter opsional untuk konten JSON format?: 'intlayer' | 'icu' | 'i18next', // default: 'intlayer' // Membagi satu file menjadi satu kamus per kunci tingkat atas (terdeteksi otomatis) splitKeys?: boolean,});format ('intlayer' | 'icu' | 'i18next')
Specifies the formatter to use for the dictionary content when loading JSON files. This allows using different message formatting syntaxes compatible with various i18n libraries.
'intlayer': The default Intlayer formatter (default).'icu': Uses ICU message formatting (compatible with libraries like react-intl, vue-i18n).'i18next': Uses i18next message formatting (compatible with i18next, next-i18next, Solid-i18next).
Example:
Salin kode ke clipboard
loadJSON({ source: ({ key }) => `./src/**/${key}.i18n.json`, locale: Locales.ENGLISH, format: "icu", // Use ICU formatting for compatibility}),splitKeys (boolean)
Perilaku yang sama seperti di syncJSON: ketika satu file JSON mengelompokkan beberapa namespace berdasarkan kunci tingkat pertamanya, setiap kunci tingkat atas menjadi kamusnya sendiri.
undefined(default): terdeteksi otomatis — dibagi ketika polasourcetidak memiliki segmen{key}, kamus tunggal jika tidak.true/false: paksa atau nonaktifkan pemisahan.
Salin kode ke clipboard
loadJSON({ source: ({ locale }) => `./messages/${locale}.json`, format: "icu", // splitKeys diaktifkan otomatis: `Hero`, `Nav`, `About`, … masing-masing menjadi kamus}),Behavior and conventions
- If your
sourcemask includes a locale placeholder, only files for the selectedlocaleare ingested. - Jika tidak ada segmen
{key}dalam mask Anda, setiap kunci tingkat atas dari file menjadi kamusnya sendiri secara default (lihatsplitKeys). AtursplitKeys: falseuntuk memuat seluruh file sebagai satu kamusindex. - Keys are derived from file paths by substituting the
{key}placeholder in yoursourcebuilder. - The plugin only uses discovered files and does not fabricate missing locales or keys.
- The
fillpath is inferred from yoursourceand used to update missing values via CLI when you opt‑in.
Conflict resolution
Ketika kunci terjemahan yang sama ada di beberapa sumber JSON:
- Plugin dengan prioritas tertinggi menentukan nilai akhir
- Sumber dengan prioritas lebih rendah digunakan sebagai cadangan untuk kunci yang hilang
- Ini memungkinkan Anda mempertahankan terjemahan legacy sambil secara bertahap bermigrasi ke struktur baru
CLI
File JSON yang disinkronkan akan dianggap sebagai file .content lainnya. Artinya, semua perintah intlayer akan tersedia untuk file JSON yang disinkronkan. Termasuk:
intlayer content testuntuk menguji apakah ada terjemahan yang hilangintlayer content listuntuk mendaftar file JSON yang disinkronkanintlayer content filluntuk mengisi terjemahan yang hilangintlayer content pushuntuk mengirim file JSON yang disinkronkanintlayer content pulluntuk menarik file JSON yang disinkronkan
Lihat Intlayer CLI untuk detail lebih lanjut.
Keterbatasan (saat ini)
- Tidak ada dukungan penyisipan atau bentuk jamak/ICU saat menargetkan pustaka pihak ketiga.
- Editor visual belum tersedia untuk runtime non-Intlayer.
- Sinkronisasi hanya untuk JSON; format katalog non-JSON tidak didukung.
Mengapa ini penting
- Kami dapat merekomendasikan solusi i18n yang sudah mapan dan memposisikan Intlayer sebagai tambahan.
- Kami memanfaatkan SEO/kata kunci mereka dengan tutorial yang berakhir dengan menyarankan Intlayer untuk mengelola JSON.
- Memperluas audiens yang dapat dijangkau dari “proyek baru” menjadi “tim mana pun yang sudah menggunakan i18n”.