--- createdAt: 2026-06-14 updatedAt: 2026-06-14 title: New Intlayer v9 - What's new? description: Discover what's new in Intlayer v9. Introducing drop-in compatibility packages for popular i18n libraries and support for Collections, Variants, and Dynamic Records. keywords: - Intlayer - Compatibility - Migration - Collections - Variants - Dynamic Records - i18next - next-intl - vue-i18n slugs: - doc - releases - v9 author: aymericzip --- # New Intlayer v9 - What's new? Welcome to Intlayer v9! This major release marks a huge milestone in simplifying the migration path to Intlayer with **Compat Adapter Packages** for major i18n libraries (`react-i18next`, `next-intl`, `vue-i18n`, etc.) and adds support for rich content structures: **Collections**, **Variants**, and **Dynamic Records**. ## Table of contents --- ## Compat Adapter Packages Migrating to Intlayer from popular i18n libraries is now easier than ever. We have created five compat packages that expose the **exact same public APIs** as standard i18n libraries but delegate all translation work to Intlayer at runtime. ### Expose Same Public API with Strict Typing By replacing imports, you get all the benefits of Intlayer (including compile-time type safety against your actual dictionaries) with minimal code changes: - `@intlayer/i18next` - `@intlayer/react-i18next` - `@intlayer/next-intl` - `@intlayer/next-i18next` - `@intlayer/vue-i18n` For example, simply change: ```ts import { useTranslation } from "react-i18next"; ``` to: ```ts import { useTranslation } from "@intlayer/react-i18next"; ``` Your keys will now be **strictly typed** against your Intlayer dictionaries, offering full dot-path auto-completion in your IDE! ### Bundler Alias Plugins (Vite, Next.js, Turbopack) To allow migrating without rewriting all your import statements manually, each compat adapter package includes a **custom bundler plugin** (Vite or Next.js) under the `/plugin` subpath. These plugins automatically rewrite existing imports (e.g. `react-i18next` or `next-intl`) to their `@intlayer/*` equivalents at build time. #### Next.js (Webpack / Turbopack) Example Instead of `withIntlayer`, wrap your Next.js configuration with the 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); ``` #### Vite (React, Vue, Solid, Svelte) Example ```ts fileName="vite.config.ts" import vueI18nVitePlugin from "@intlayer/vue-i18n/plugin"; export default defineConfig({ plugins: [vueI18nVitePlugin()], }); ``` --- ## Mutualized Runtime Resolver All compat adapters now route translation resolution through a single, highly optimised runtime parser: `@intlayer/core/messageFormat`. - **Interpolate Message**: Resolves standard `{{var}}` (whitespace & dot-paths), ICU formatted args (`{v, number, percent}` etc.), and bare `{var}` templates. - **Message Node Resolver**: Resolves nested nodes: `insert()`, `plural()` (CLDR plural rules), `enu()` (enumeration), `gender()`, HTML tags, arrays, and callable function nodes. - **Tokenised Tag Parser**: Supports inline XML/HTML tags and numbered tags (e.g., `<1>children`) to power rich-text rendering out of the box. --- ## Feature Spec: Collections, Variants & Dynamic Records Intlayer v9 expands beyond static key-value objects, allowing dictionaries to declare dynamic layout structures that are fully typed end-to-end. ### 1. Collections Define a CMS-managed list of ordered items (e.g. FAQs, products, or blog lists): ```ts fileName="faq.content.ts" import { t, type Dictionary } from "intlayer"; export default { key: "faq", content: [ { question: t({ en: "What is Intlayer?", fr: "Qu'est-ce qu'Intlayer ?" }), answer: t({ en: "An i18n toolkit.", fr: "Une boîte à outils i18n." }), }, ], } satisfies Dictionary; ``` #### Usage: ```ts // Fetch all items const allFaqs = useIntlayer("faq"); // -> { question: string, answer: string }[] // Fetch single item by index const faq = useIntlayer("faq", { item: 1 }); // -> { question: string, answer: string } ``` ### 2. Variants Deliver A/B tests, seasonal headers, feature flags, or custom landing pages: ```ts fileName="hero.content.ts" import { t, type Dictionary } from "intlayer"; export default { key: "hero-banner", variant: "default", content: { control: t({ en: "Welcome", fr: "Bienvenue" }), black_friday: t({ en: "Shop now", fr: "Acheter maintenant" }), }, } satisfies Dictionary; ``` #### Usage: ```ts const banner = useIntlayer("hero-banner", { variant: "black_friday" }); ``` ### 3. Dynamic Records Define dictionaries whose entries are loaded dynamically at runtime via query IDs: ```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({ en: "Clean Code", fr: "Code Propre" }), }, } satisfies Dictionary; ``` #### Usage: ```ts // Fetches only the requested item dynamically (requires Suspense) const product = useIntlayer("product-copy", { id: "prod_123", category: "books", }); ``` --- ## Dynamic Loading & Bundle Size Optimisations To keep bundles extremely small, Intlayer v9 supports dynamic lazy loading. In your configuration, set `importMode` to `'dynamic'` or `'fetch'`: ```ts fileName="intlayer.config.ts" export default { dictionary: { importMode: "dynamic", // "static" | "dynamic" | "fetch" }, }; ``` At build time, `@intlayer/swc` and `@intlayer/babel` scan your files and replace `useIntlayer` / `getIntlayer` calls with tree-shakeable wrappers (`useDictionary` / `useDictionaryDynamic`). Only the content required for the selected collection item, variant, or locale is loaded, preventing your production bundle from containing unused translations. --- ## Migration notes from v8 If you are upgrading from v8, note that the v9 does not include breaking changes. But here are the key changes: - **Locales & Dialects**: If using external i18n dependencies, add their respective compat adapter plugins in your configuration or bundler setup to automatically rewrite imports. - **Custom Selectors**: When calling `useIntlayer`, the second parameter is now reserved for an option object containing `{ locale, item, variant, id }`. If you previously passed a locale string directly, you can still do so, but using the options object is recommended for advanced selections. --- ## Useful links - [Compat Adapter Packages Guide](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en/compat/index.md) - [Dynamic Dictionaries - Collections, Variants & Dynamic Records](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en/dynamic_dictionaries/index.md) - [Configuration Reference](https://github.com/aymericzip/intlayer/blob/main/docs/docs/en/configuration.md)