Đặt câu hỏi và nhận tóm tắt tài liệu bằng cách tham chiếu trang này và nhà cung cấp AI bạn chọn
Lịch sử phiên bản
- "Thêm tùy chọn splitKeys (một từ điển cho mỗi khóa namespace cấp cao nhất) cho bố cục tệp đơn của next-intl / react-intl"v9.0.021/6/2026
- "Thêm hỗ trợ định dạng ICU và i18next"v7.5.013/12/2025
- "Tài liệu Plugin Đồng bộ JSON ban đầu"v6.1.65/10/2025
Nội dung của trang này đã được dịch bằng AI.
Xem phiên bản mới nhất của nội dung gốc bằng tiếng AnhIf 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
Đồng bộ JSON (cầu nối i18n) - Đồng bộ JSON với hỗ trợ ICU / i18next
Sử dụng Intlayer như một tiện ích bổ sung cho bộ công cụ i18n hiện có của bạn. Plugin này giữ cho các thông điệp JSON của bạn đồng bộ với từ điển Intlayer để bạn có thể:
- Giữ nguyên i18next, next-intl, react-intl, vue-i18n, next-translate, nuxt-i18n, Solid-i18next, svelte-i18n, v.v.
- Quản lý và dịch các thông điệp của bạn với Intlayer (CLI, CI, nhà cung cấp, CMS), mà không cần tái cấu trúc ứng dụng của bạn.
- Phát hành các hướng dẫn và nội dung SEO nhắm mục tiêu từng hệ sinh thái, đồng thời đề xuất Intlayer như lớp quản lý JSON.
Ghi chú và phạm vi hiện tại:
- Việc ngoại hóa sang CMS hoạt động cho cả bản dịch và văn bản cổ điển.
- Chưa hỗ trợ chèn, số nhiều/ICU, hoặc các tính năng runtime nâng cao của các thư viện khác.
- Trình chỉnh sửa trực quan chưa được hỗ trợ cho các đầu ra i18n của bên thứ ba.
Khi nào nên sử dụng plugin này
- Bạn đã sử dụng một thư viện i18n và lưu trữ các thông điệp trong các tệp JSON.
- Bạn muốn hỗ trợ điền bằng AI, kiểm tra trong CI, và vận hành nội dung mà không thay đổi runtime kết xuất của bạn.
Cài đặt
Sao chép mã vào clipboard
pnpm add -D @intlayer/sync-json-plugin# hoặcnpm 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
Sao chép mã vào 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
Add the plugin to your intlayer.config.ts and point it at your existing JSON structure.
Sao chép mã vào 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, }, // Giữ cho các tệp JSON hiện tại của bạn đồng bộ với từ điển Intlayer plugins: [ syncJSON({ // Bố cục theo từng locale, từng namespace (ví dụ: next-intl, i18next với namespaces) source: ({ key, locale }) => `./locales/${locale}/${key}.json`, format: "icu", }), ],};export default config;Phương án thay thế: một tệp duy nhất cho mỗi locale (thường dùng với i18next/react-intl):
Sao chép mã vào 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;Cách hoạt động
- Đọc: plugin phát hiện các tệp JSON từ builder
sourcecủa bạn và tải chúng như các từ điển Intlayer. - Ghi: sau khi build và điền, plugin ghi các tệp JSON đã được bản địa hóa trở lại cùng đường dẫn (với một dòng mới cuối cùng để tránh lỗi định dạng).
- Tự động điền: plugin khai báo một đường dẫn
autoFillcho mỗi từ điển. Chạy lệnhintlayer fillsẽ chỉ cập nhật các bản dịch còn thiếu trong các tệp JSON của bạn theo mặc định.
API:
Sao chép mã vào clipboard
syncJSON({ source: ({ key, locale }) => string, // bắt buộc location?: string, // nhãn tùy chọn, mặc định: "plugin" priority?: number, // ưu tiên tùy chọn để giải quyết xung đột, mặc định: 0 format?: 'intlayer' | 'icu' | 'i18next', // bộ định dạng tùy chọn, được sử dụng cho tương thích runtime Intlayer splitKeys?: boolean, // tùy chọn, chia một tệp thành một từ điển cho mỗi khóa cấp cao nhất (tự động phát hiện)});format ('intlayer' | 'icu' | 'i18next')
Chỉ định bộ định dạng sẽ được sử dụng cho nội dung từ điển khi đồng bộ hóa các tệp JSON. Điều này cho phép sử dụng các cú pháp định dạng thông báo khác nhau tương thích với runtime Intlayer.
undefined: Không sử dụng bộ định dạng nào, nội dung JSON sẽ được sử dụng nguyên trạng.'intlayer': Bộ định dạng Intlayer mặc định (mặc định).'icu': Sử dụng định dạng thông báo ICU (tương thích với các thư viện như react-intl, vue-i18n).'i18next': Sử dụng định dạng thông báo i18next (tương thích với i18next, next-i18next, Solid-i18next).
Lưu ý rằng việc sử dụng bộ định dạng sẽ chuyển đổi nội dung JSON của bạn ở đầu vào và đầu ra. Đối với các quy tắc JSON phức tạp như số nhiều ICU, việc phân tích có thể không đảm bảo ánh xạ 1 đối 1 giữa đầu vào và đầu ra. Nếu bạn không sử dụng runtime Intlayer, bạn có thể muốn không thiết lập bộ định dạng.
Ví dụ:
Sao chép mã vào clipboard
syncJSON({ source: ({ key, locale }) => `./locales/${locale}/${key}.json`, format: "i18next", // Sử dụng định dạng i18next để tương thích}),splitKeys (boolean)
Kiểm soát liệu một tệp JSON duy nhất mà các khóa cấp đầu tiên là các namespace có nên trở thành một từ điển cho mỗi khóa cấp cao nhất, thay vì một từ điển duy nhất chứa toàn bộ tệp.
Điều này phù hợp với mô hình namespace của các thư viện như next-intl và react-intl, nơi một tệp messages/{locale}.json nhóm nhiều namespace theo các khóa cấp đầu tiên của nó, mỗi khóa được xử lý độc lập (ví dụ: useTranslations('Hero') phân giải thành từ điển Hero).
undefined(mặc định): tự động phát hiện — tệp được chia khi mẫusourcekhông có phân đoạn{key}(một tệp chứa mọi namespace), và được giữ dưới dạng một từ điển duy nhất nếu không (một tệp cho mỗi khóa).true: luôn chia mỗi khóa cấp cao nhất thành từ điển riêng của nó.false: không bao giờ chia; toàn bộ tệp trở thành một từ điển duy nhất.
Given a single messages/{locale}.json file:
Sao chép mã vào clipboard
{ "Hero": { "title": "Full-stack developer" }, "Nav": { "work": "Work", "about": "About" }, "About": { "lead": "I build apps end to end." }}Sao chép mã vào clipboard
syncJSON({ format: "icu", source: ({ locale }) => `./messages/${locale}.json`, // splitKeys: true, // implied because the pattern has no `{key}` segment}),Điều này tạo ra ba từ điển — Hero, Nav, và About — do đó useTranslations('Hero') (next-intl) phân giải chính xác. Khi ghi lại, tất cả các namespace được tập hợp lại vào cùng một tệp theo từng locale.
Khi bạn giữ phân đoạn{key}rõ ràng trongsourcecủa mình (ví dụ:./locales/${locale}/${key}.json), mỗi tệp đã là một namespace, vì vậy việc chia tách bị tắt theo mặc định.
Multiple JSON sources and priority
You can add multiple syncJSON plugins to synchronize different JSON sources. This is useful when you have multiple i18n libraries or different JSON structures in your project.
Priority system
When multiple plugins target the same dictionary key, the priority parameter determines which plugin takes precedence:
- Higher priority numbers win over lower ones
- Default priority of
.contentfiles is0 - Default priority of plugins is
0 - Plugins with the same priority are processed in the order they appear in the configuration
Sao chép mã vào 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: [ // Nguồn JSON chính (ưu tiên cao nhất) syncJSON({ format: "i18next", source: ({ key, locale }) => `./locales/${locale}/${key}.json`, location: "main-translations", priority: 10, }), // Nguồn JSON dự phòng (ưu tiên thấp hơn) syncJSON({ format: "i18next", source: ({ locale }) => `./fallback-locales/${locale}.json`, location: "fallback-translations", priority: 5, }), // Nguồn JSON kế thừa (ưu tiên thấp nhất) 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):
Sao chép mã vào 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):
Sao chép mã vào 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
Sao chép mã vào clipboard
loadJSON({ // Build paths to your JSON. `locale` is optional if your structure has no locale segment source: ({ key, locale }) => string, // Target locale for the dictionaries loaded by this plugin instance // Defaults to configuration.internationalization.defaultLocale locale?: Locale, // Optional label to identify the source location?: string, // default: "plugin" // Priority used for conflict resolution against other sources priority?: number, // default: 0 // Optional formatter for the JSON content format?: 'intlayer' | 'icu' | 'i18next', // default: 'intlayer' // Split a single file into one dictionary per top-level key (auto-detected) splitKeys?: boolean,});format ('intlayer' | 'icu' | 'i18next')
Chỉ định bộ định dạng sẽ được sử dụng cho nội dung từ điển khi tải các tệp JSON. Điều này cho phép sử dụng các cú pháp định dạng thông báo khác nhau tương thích với các thư viện i18n khác nhau.
'intlayer': Bộ định dạng Intlayer mặc định (mặc định).'icu': Sử dụng định dạng thông báo ICU (tương thích với các thư viện như react-intl, vue-i18n).'i18next': Sử dụng định dạng thông báo i18next (tương thích với i18next, next-i18next, Solid-i18next).
Ví dụ:
Sao chép mã vào clipboard
loadJSON({ source: ({ key }) => `./src/**/${key}.i18n.json`, locale: Locales.ENGLISH, format: "icu", // Sử dụng định dạng ICU để tương thích}),splitKeys (boolean)
Hành vi tương tự như trong syncJSON: khi một tệp JSON duy nhất nhóm nhiều namespace theo các khóa cấp đầu tiên của nó, mỗi khóa cấp cao nhất sẽ trở thành từ điển riêng của nó.
undefined(mặc định): tự động phát hiện — chia khi mẫusourcekhông có phân đoạn{key}, nếu không thì là một từ điển duy nhất.true/false: buộc hoặc tắt chia tách.
Sao chép mã vào clipboard
loadJSON({ source: ({ locale }) => `./messages/${locale}.json`, format: "icu", // splitKeys auto-enabled: `Hero`, `Nav`, `About`, … each become a dictionary}),Behavior and conventions
- If your
sourcemask includes a locale placeholder, only files for the selectedlocaleare ingested. - Nếu không có phân đoạn
{key}trong mặt nạ của bạn, mỗi khóa cấp cao nhất của tệp sẽ trở thành từ điển riêng của nó theo mặc định (xemsplitKeys). ĐặtsplitKeys: falseđể thay vào đó tải toàn bộ tệp dưới dạng một từ điểnindexduy nhất. - 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
When the same translation key exists in multiple JSON sources:
- The plugin with the highest priority determines the final value
- Lower priority sources are used as fallbacks for missing keys
- This allows you to maintain legacy translations while gradually migrating to new structures
CLI
Các tệp JSON được đồng bộ sẽ được coi như các tệp .content khác. Điều đó có nghĩa là tất cả các lệnh intlayer sẽ có sẵn cho các tệp JSON được đồng bộ. Bao gồm:
intlayer content testđể kiểm tra xem có bản dịch nào bị thiếu khôngintlayer content listđể liệt kê các tệp JSON được đồng bộintlayer content fillđể điền các bản dịch bị thiếuintlayer content pushđể đẩy các tệp JSON được đồng bộ lênintlayer content pullđể kéo các tệp JSON được đồng bộ về
Xem Intlayer CLI để biết thêm chi tiết.
Limitations (current)
- Không hỗ trợ chèn hoặc số nhiều/ICU khi nhắm mục tiêu các thư viện bên thứ ba.
- Trình chỉnh sửa trực quan chưa có sẵn cho các runtime không phải Intlayer.
- Chỉ đồng bộ JSON; không hỗ trợ các định dạng danh mục không phải JSON.
Why this matters
- Chúng ta có thể đề xuất các giải pháp i18n đã được thiết lập và định vị Intlayer như một tiện ích bổ sung.
- Chúng ta tận dụng SEO/từ khóa của họ với các hướng dẫn kết thúc bằng việc gợi ý sử dụng Intlayer để quản lý JSON.
- Mở rộng đối tượng người dùng từ “dự án mới” sang “bất kỳ nhóm nào đã sử dụng i18n”.