--- createdAt: 2026-06-14 updatedAt: 2026-06-14 title: Intlayer v9 Mới - Có gì mới? description: Khám phá các tính năng mới trong Intlayer v9. Giới thiệu các package tương thích drop-in cho các thư viện i18n phổ biến và hỗ trợ Collections, Variants, và Dynamic Records. keywords: - Intlayer - Compatibility - Migration - Collections - Variants - Dynamic Records - i18next - next-intl - vue-i18n slugs: - doc - releases - v9 author: aymericzip --- # Intlayer v9 Mới - Có gì mới? Chào mừng bạn đến với Intlayer v9! Bản phát hành lớn này đánh dấu một cột mốc quan trọng trong việc đơn giản hóa lộ trình migration sang Intlayer với các **Compat Adapter Packages** dành cho các thư viện i18n phổ biến (`react-i18next`, `next-intl`, `vue-i18n`, v.v.) và bổ sung hỗ trợ cho các cấu trúc nội dung phong phú: **Collections**, **Variants**, và **Dynamic Records**. ## Mục lục --- ## Compat Adapter Packages Việc migration sang Intlayer từ các thư viện i18n phổ biến giờ đây dễ dàng hơn bao giờ hết. Chúng tôi đã tạo ra năm compat package cung cấp **chính xác các public API tương tự** như các thư viện i18n tiêu chuẩn nhưng ủy quyền toàn bộ việc xử lý translation cho Intlayer tại runtime. ### Cung cấp cùng một Public API với Strict Typing Bằng cách thay thế các import, bạn sẽ nhận được tất cả các lợi ích của Intlayer (bao gồm cả compile-time type safety dựa trên các dictionary thực tế của bạn) với những thay đổi code tối thiểu: - `@intlayer/i18next` - `@intlayer/react-i18next` - `@intlayer/next-intl` - `@intlayer/next-i18next` - `@intlayer/vue-i18n` Ví dụ, chỉ cần thay đổi: ```ts import { useTranslation } from "react-i18next"; ``` thành: ```ts import { useTranslation } from "@intlayer/react-i18next"; ``` Các key của bạn giờ đây sẽ được **strictly typed** dựa trên các Intlayer dictionary của bạn, mang lại khả năng auto-completion dot-path đầy đủ trong IDE của bạn! ### Bundler Alias Plugins (Vite, Next.js, Turbopack) Để cho phép migration mà không cần phải viết lại tất cả các câu lệnh import một cách thủ công, mỗi compat adapter package đều đi kèm một **custom bundler plugin** (Vite hoặc Next.js) dưới subpath `/plugin`. Các plugin này tự động rewrite các import hiện có (ví dụ: `react-i18next` hoặc `next-intl`) thành các package tương đương `@intlayer/*` tại build time. #### Ví dụ Next.js (Webpack / Turbopack) Thay vì `withIntlayer`, hãy bọc cấu hình Next.js của bạn bằng compat plugin: ```ts fileName="next.config.ts" import { createNextI18nPlugin } from "@intlayer/next-i18next/plugin"; import type { NextConfig } from "next"; const withIntlayer = createNextI18nPlugin(); const nextConfig: NextConfig = {}; export default withIntlayer(nextConfig); ``` #### Ví dụ Vite (React, Vue, Solid, Svelte) ```ts fileName="vite.config.ts" import vueI18nVitePlugin from "@intlayer/vue-i18n/plugin"; export default defineConfig({ plugins: [vueI18nVitePlugin()], }); ``` --- ## Mutualized Runtime Resolver Tất cả các compat adapter giờ đây đều định tuyến việc xử lý translation thông qua một runtime parser duy nhất và được tối ưu hóa cao: `@intlayer/core/messageFormat`. - **Interpolate Message**: Xử lý các cú pháp tiêu chuẩn `{{var}}` (whitespace & dot-paths), các đối số định dạng ICU (`{v, number, percent}` v.v.), và các template `{var}` cơ bản. - **Message Node Resolver**: Xử lý các node lồng nhau: `insert()`, `plural()` (quy tắc số nhiều CLDR), `enu()` (enumeration), `gender()`, các thẻ HTML, array, và các callable function node. - **Tokenized Tag Parser**: Hỗ trợ các thẻ XML/HTML inline và các thẻ được đánh số (ví dụ: `<1>children`) để hỗ trợ render rich-text một cách dễ dàng. --- ## Chi tiết tính năng: Collections, Variants & Dynamic Records Intlayer v9 mở rộng vượt ra ngoài các đối tượng key-value tĩnh, cho phép các dictionary khai báo các cấu trúc layout động được định kiểu đầy đủ (fully typed) từ đầu đến cuối. ### 1. Collections Định nghĩa một danh sách các item có thứ tự do CMS quản lý (ví dụ: FAQ, sản phẩm, hoặc danh sách blog): ```ts fileName="faq.content.ts" import { t, type Dictionary } from "intlayer"; export default { key: "faq", content: [ { question: t({ vi: "Intlayer là gì?", en: "What is Intlayer?", fr: "Qu'est-ce qu'Intlayer ?", }), answer: t({ vi: "Một bộ công cụ i18n.", en: "An i18n toolkit.", fr: "Une boîte à outils i18n.", }), }, ], } satisfies Dictionary; ``` #### Cách sử dụng: ```ts // Lấy tất cả các item const allFaqs = useIntlayer("faq"); // -> { question: string, answer: string }[] // Lấy một item duy nhất bằng index const faq = useIntlayer("faq", { item: 1 }); // -> { question: string, answer: string } ``` ### 2. Variants Cung cấp các bản thử nghiệm A/B, seasonal header, feature flag, hoặc các landing page tùy chỉnh: ```ts fileName="hero.content.ts" import { t, type Dictionary } from "intlayer"; export default { key: "hero-banner", variant: "default", content: { control: t({ vi: "Chào mừng", en: "Welcome", fr: "Bienvenue" }), black_friday: t({ vi: "Mua ngay", en: "Shop now", fr: "Acheter maintenant", }), }, } satisfies Dictionary; ``` #### Cách sử dụng: ```ts const banner = useIntlayer("hero-banner", { variant: "black_friday" }); ``` ### 3. Dynamic Records Định nghĩa các dictionary có các mục nhập được tải động tại runtime thông qua các query ID: ```ts fileName="product.content.ts" import { t, type Dictionary } from "intlayer"; export default { key: "product-copy", meta: { id: "prod_123", category: "books", }, content: { title: t({ vi: "Clean Code", en: "Clean Code", fr: "Code Propre" }), }, } satisfies Dictionary; ``` #### Cách sử dụng: ```ts // Chỉ tải động item được yêu cầu (yêu cầu Suspense) const product = useIntlayer("product-copy", { id: "prod_123", category: "books", }); ``` --- ## Tối ưu hóa Dynamic Loading & Bundle Size Để giữ cho các bundle cực kỳ nhỏ gọn, Intlayer v9 hỗ trợ dynamic lazy loading. Trong cấu hình của bạn, hãy đặt `importMode` thành `'dynamic'` hoặc `'fetch'`: ```ts fileName="intlayer.config.ts" export default { dictionary: { importMode: "dynamic", // "static" | "dynamic" | "fetch" }, }; ``` Tại build time, `@intlayer/swc` và `@intlayer/babel` sẽ quét các file của bạn và thay thế các lệnh gọi `useIntlayer` / `getIntlayer` bằng các wrapper có khả năng tree-shake (`useDictionary` / `useDictionaryDynamic`). Chỉ nội dung được yêu cầu cho collection item, variant, hoặc locale đã chọn mới được tải, giúp ngăn production bundle của bạn chứa các bản dịch không sử dụng. --- ## Lưu ý khi migration từ v8 Nếu bạn đang nâng cấp từ v8, lưu ý rằng v9 không bao gồm các breaking change. Tuy nhiên, dưới đây là các thay đổi chính: - **Locales & Dialects**: Nếu sử dụng các dependency i18n bên ngoài, hãy thêm các compat adapter plugin tương ứng của chúng vào cấu hình hoặc thiết lập bundler của bạn để tự động rewrite các import. - **Custom Selectors**: Khi gọi `useIntlayer`, tham số thứ hai giờ đây được dành riêng cho một đối tượng option chứa `{ locale, item, variant, id }`. Nếu trước đây bạn đã truyền trực tiếp một chuỗi locale, bạn vẫn có thể làm như vậy, nhưng việc sử dụng đối tượng options được khuyến nghị cho các lựa chọn nâng cao. --- ## Liên kết hữu ích - [Hướng dẫn về Compat Adapter Packages](https://github.com/aymericzip/intlayer/blob/main/docs/docs/vi/compat/index.md) - [Dynamic Dictionaries - Collections, Variants & Dynamic Records](https://github.com/aymericzip/intlayer/blob/main/docs/docs/vi/dynamic_dictionaries/index.md) - [Tài liệu tham khảo cấu hình](https://github.com/aymericzip/intlayer/blob/main/docs/docs/vi/configuration.md)