Автор:
    Создание:2026-06-14Последнее обновление:2026-06-14

    Новый Intlayer v9 — Что нового?

    Добро пожаловать в Intlayer v9! Этот мажорный релиз знаменует собой важную веху в упрощении миграции на Intlayer благодаря пакетам адаптеров совместимости (Compat Adapter Packages) для популярных библиотек i18n (react-i18next, next-intl, vue-i18n и др.), а также добавляет поддержку сложных структур контента: Collections (Коллекции), Variants (Варианты) и Dynamic Records (Динамические записи).

    Содержание


    Пакеты адаптеров совместимости (Compat Adapter Packages)

    Миграция на Intlayer с популярных библиотек i18n стала проще, чем когда-либо. Мы создали пять пакетов совместимости (compat packages), которые предоставляют точно такой же публичный API, как и стандартные библиотеки i18n, но делегируют всю работу по переводу в Intlayer во время выполнения (runtime).

    Тот же публичный API со строгой типизацией

    Просто заменив импорты, вы получаете все преимущества Intlayer (включая безопасность типов на этапе компиляции на основе ваших реальных словарей) с минимальными изменениями в коде:

    • @intlayer/i18next
    • @intlayer/react-i18next
    • @intlayer/next-intl
    • @intlayer/next-i18next
    • @intlayer/vue-i18n

    Например, просто замените:

    ts
    import { useTranslation } from "react-i18next";

    на:

    ts
    import { useTranslation } from "@intlayer/react-i18next";

    Теперь ваши ключи будут строго типизированы на основе словарей Intlayer, обеспечивая автодополнение путей через точку (dot-path) в вашей IDE!

    Плагины-алиасы для сборщиков (Vite, Next.js, Turbopack)

    Чтобы позволить мигрировать без ручной перезаписи всех импортов, каждый пакет адаптера совместимости включает в себя кастомный плагин для сборщика (Vite или Next.js) по подпути /plugin.

    Эти плагины автоматически перезаписывают существующие импорты (например, react-i18next или next-intl) на их эквиваленты @intlayer/* во время сборки.

    Пример для Next.js (Webpack / Turbopack)

    Вместо withIntlayer оберните вашу конфигурацию Next.js плагином совместимости:

    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)

    vite.config.ts
    import vueI18nVitePlugin from "@intlayer/vue-i18n/plugin";export default defineConfig({  plugins: [vueI18nVitePlugin()],});

    Единый резолвер рантайма (Mutualized Runtime Resolver)

    Все адаптеры совместимости теперь направляют разрешение переводов через единый, высокооптимизированный парсер рантайма: @intlayer/core/messageFormat.

    • Интерполяция сообщений (Interpolate Message): Разрешает стандартные шаблоны {{var}} (с пробелами и путями через точку), аргументы в формате ICU ({v, number, percent} и т. д.) и простые шаблоны {var}.
    • Резолвер узлов сообщений (Message Node Resolver): Разрешает вложенные узлы: insert(), plural() (плюрализация по правилам CLDR), enu() (перечисление), gender() (род), HTML-теги, массивы и вызываемые функции-узлы.
    • Токенизированный парсер тегов (Tokenized Tag Parser): Поддерживает встроенные XML/HTML-теги и нумерованные теги (например, <1>children</1>) для рендеринга форматированного текста (rich-text) из коробки.

    Спецификация функций: Collections, Variants и Dynamic Records

    Intlayer v9 выходит за рамки статических объектов типа ключ-значение, позволяя словарям объявлять динамические структуры макетов со сквозной типизацией.

    1. Коллекции (Collections)

    Определяйте управляемый CMS упорядоченный список элементов (например, FAQ, товары или списки блогов):

    faq.content.ts
    import { t, type Dictionary } from "intlayer";export default {  key: "faq",  content: [    {      question: t({        ru: "Что такое Intlayer?",        en: "What is Intlayer?",        fr: "Qu'est-ce qu'Intlayer ?",      }),      answer: t({        ru: "Инструментарий i18n.",        en: "An i18n toolkit.",        fr: "Une boîte à outils i18n.",      }),    },  ],} satisfies Dictionary;

    Использование:

    ts
    // Получить все элементыconst allFaqs = useIntlayer("faq"); // -> { question: string, answer: string }[]// Получить один элемент по индексуconst faq = useIntlayer("faq", { item: 1 }); // -> { question: string, answer: string }

    2. Варианты (Variants)

    Используйте для A/B-тестирования, сезонных заголовков, фича-флагов или кастомных целевых страниц:

    hero.content.ts
    import { t, type Dictionary } from "intlayer";export default {  key: "hero-banner",  variant: "default",  content: {    control: t({ ru: "Добро пожаловать", en: "Welcome", fr: "Bienvenue" }),    black_friday: t({      ru: "Купить сейчас",      en: "Shop now",      fr: "Acheter maintenant",    }),  },} satisfies Dictionary;

    Использование:

    ts
    const banner = useIntlayer("hero-banner", { variant: "black_friday" });

    3. Динамические записи (Dynamic Records)

    Определяйте словари, записи которых загружаются динамически во время выполнения по идентификаторам запросов:

    product.content.ts
    import { t, type Dictionary } from "intlayer";export default {  key: "product-copy",  meta: {    id: "prod_123",    category: "books",  },  content: {    title: t({ ru: "Чистый код", en: "Clean Code", fr: "Code Propre" }),  },} satisfies Dictionary;

    Использование:

    ts
    // Динамически загружает только запрошенный элемент (требуется Suspense)const product = useIntlayer("product-copy", {  id: "prod_123",  category: "books",});

    Динамическая загрузка и оптимизация размера бандла

    Чтобы сохранять размер бандлов минимальным, Intlayer v9 поддерживает динамическую ленивую загрузку (lazy loading).

    В вашей конфигурации установите importMode в значение 'dynamic' или 'fetch':

    intlayer.config.ts
    export default {  dictionary: {    importMode: "dynamic", // "static" | "dynamic" | "fetch"  },};

    Во время сборки @intlayer/swc и @intlayer/babel сканируют ваши файлы и заменяют вызовы useIntlayer / getIntlayer на tree-shakeable обертки (useDictionary / useDictionaryDynamic). Загружается только контент, необходимый для выбранного элемента коллекции, варианта или локали, что предотвращает попадание неиспользуемых переводов в ваш продакшн-бандл.


    Примечания по миграции с v8

    Если вы обновляетесь с v8, обратите внимание, что v9 не содержит ломающих изменений (breaking changes). Однако вот ключевые изменения:

    • Локали и диалекты (Locales & Dialects): Если вы используете внешние зависимости i18n, добавьте соответствующие плагины адаптеров совместимости в вашу конфигурацию или настройки сборщика для автоматической перезаписи импортов.
    • Кастомные селекторы (Custom Selectors): При вызове useIntlayer второй параметр теперь зарезервирован для объекта опций, содержащего { locale, item, variant, id }. Если ранее вы передавали строку локали напрямую, вы все еще можете это делать, но для расширенного выбора рекомендуется использовать объект опций.

    Полезные ссылки