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

    Варианты

    Вариант — это набор файлов контента, которые имеют общий ключ словаря (key), но каждый несёт своё значение variant. Intlayer отдаёт нужный файл на основе селектора, переданного в useIntlayer.

    Значение variant может принимать две формы:

    • Строка — одна именованная альтернатива (A/B-тесты, сезонные баннеры, feature-флаги).
    • Объект — структурированный дискриминатор, адресуемый набором полей (записи CMS, контент конкретного пользователя, любой контент с непрозрачным ID в качестве ключа). Идентичностью является весь объект: селектор должен предоставить равный объект, чтобы разрешить запись.
    Объектная форма заменяет прежнее поле meta. Везде, где раньше вы писали meta: { id, … }, пишите variant: { id, … } и выбирайте её через { variant: { id, … } }.

    Именованные (строковые) варианты

    Каждый файл представляет одну именованную альтернативу. Пропуск variant (или значение "default") помечает его как запасной вариант.

    hero-banner.content.ts
    import { t, type Dictionary } from "intlayer";
    
    const dictionary = {
      key: "hero-banner",
      variant: "default",
      content: {
        headline: t({
          en: "Build faster with Intlayer",
          fr: "Développez plus vite avec Intlayer",
        }),
        cta: t({ en: "Get started", fr: "Commencer" }),
      },
    } satisfies Dictionary;
    
    export default dictionary;
    hero-banner.black-friday.content.ts
    import { t, type Dictionary } from "intlayer";
    
    const dictionary = {
      key: "hero-banner",
      variant: "black_friday",
      content: {
        headline: t({
          en: "50 % off — today only",
          fr: "−50 % — aujourd'hui seulement",
        }),
        cta: t({ en: "Shop now", fr: "Acheter maintenant" }),
      },
    } satisfies Dictionary;
    
    export default dictionary;

    Частичные варианты

    Вариант объявляет только ключи, которые он переопределяет; остальные наследуются из записи по умолчанию.

    hero-banner.summer.content.ts
    import { t, type Dictionary } from "intlayer";
    
    const dictionary = {
      key: "hero-banner",
      variant: "summer",
      content: {
        headline: t({
          en: "Build faster all summer",
          fr: "Développez plus vite tout l'été",
        }),
      },
    } satisfies Dictionary;
    
    export default dictionary;
    tsx
    useIntlayer("hero-banner", { variant: "summer" });// → { headline: "Développez plus vite tout l'été", cta: "Commencer" } — `cta` унаследованоuseIntlayer("hero-banner", { variant: "never-declared" });// → запись по умолчанию

    Поэтому вы добавляете файл варианта только там, где текст действительно отличается. Ключ разрешается в null только в том случае, если он объявляет варианты, но не имеет записи по умолчанию.

    Использование именованных вариантов

    Вариант по умолчанию

    Hero.tsx
    import { useIntlayer } from "react-intlayer";
    
    export const Hero = () => {
      const { headline, cta } = useIntlayer("hero-banner");
      // → вариант по умолчанию
    
      return (
        <section>
          <h1>{headline}</h1>
          <a>{cta}</a>
        </section>
      );
    };

    Именованный вариант

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

    Именованный вариант с явной локалью

    tsx
    const content = useIntlayer("hero-banner", {  variant: "black_friday",  locale: "fr",});

    Объектные (структурированные) варианты

    Объектный вариант адресует контент произвольным набором пар ключ-значение, объявленных в поле variant, — что позволяет моделировать записи CMS, контент конкретного пользователя или любой контент с непрозрачным ID в качестве ключа. Идентичностью является весь объект: селектор должен предоставить равный объект, чтобы запись была разрешена.

    product.abc.content.ts
    import { t, type Dictionary } from "intlayer";
    
    const dictionary = {
      key: "product",
      variant: { id: "prod_abc", userId: "user_123" },
      content: {
        name: t({ en: "Widget Pro", fr: "Widget Pro" }),
        description: t({ en: "The best widget.", fr: "Le meilleur widget." }),
      },
    } satisfies Dictionary;
    
    export default dictionary;
    product.abcd.content.ts
    import { t, type Dictionary } from "intlayer";
    
    const dictionary = {
      key: "product",
      variant: { id: "prod_abcd", userId: "user_123" },
      content: {
        name: t({ en: "Widget Lite", fr: "Widget Lite" }),
        description: t({ en: "A lighter option.", fr: "Une option plus légère." }),
      },
    } satisfies Dictionary;
    
    export default dictionary;

    Использование объектных вариантов

    Передайте соответствующий объект в variant. Каждое поле, объявленное в словаре, должно быть предоставлено и равно; иначе результат — null. Порядок полей не имеет значения.

    Product.tsx
    import { useIntlayer } from "react-intlayer";
    
    export const Product = ({
      productId,
      userId,
    }: {
      productId: string;
      userId: string;
    }) => {
      const content = useIntlayer("product", {
        variant: { id: productId, userId },
      });
    
      if (!content) return null;
    
      return <p>{content.description}</p>;
    };

    С явной локалью

    tsx
    const content = useIntlayer("product", {  variant: { id: "prod_abc", userId: "user_123" },  locale: "fr",});

    Отсутствует поле — нет совпадения

    ts
    // Возвращает null: отсутствует `userId`, поэтому объект не совпадает с объявленным вариантомconst content = useIntlayer("product", { variant: { id: "prod_abc" } });

    Внешний вариант

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

    Не оборачивайте useIntlayer в собственный хук, чтобы их подставить. Оптимизация на этапе сборки переписывает только литеральный вызов useIntlayer("key"), импортированный из пакета фреймворка, поэтому ничто за обёрткой не попадёт в бандл.

    Вместо этого объявите вариант один раз на провайдере, точно так же, как locale:

    App.tsx
    import { IntlayerProvider } from "react-intlayer";
    
    export const App = ({ locale, schoolType }) => (
      <IntlayerProvider locale={locale} variant={schoolType}>
        <Hero />
      </IntlayerProvider>
    );

    Теперь каждое чтение словаря под провайдером разрешается с этим вариантом, а селектор в месте вызова всегда побеждает:

    tsx
    useIntlayer("hero-banner");// → вариант провайдераuseIntlayer("hero-banner", { variant: "summer" });// → "summer" — заменяет вариант провайдера, а не дополняет его

    Формы

    Проп variant принимает три формы:

    Форма Значение
    variant="school1" один именованный вариант для всех ключей
    variant={["school1", "default"]} упорядоченная цепочка предпочтений
    variant={{ "hero-banner": "school1", default: "base" }} свой вариант для каждого ключа словаря

    Цепочка предпочтений

    Цепочка перебирается слева направо по записям, объявленным каждым ключом, и побеждает первая объявленная. Если не объявлена ни одна, используется неявная запись по умолчанию — точно так же, как для одиночного значения.

    tsx
    <IntlayerProvider variant={["school1", "school2"]} />// `hero-banner` не объявляет запись `school1`, но объявляет `school2` → "school2"// ключ, не объявляющий ни одной из них → запись по умолчанию

    Таким образом, ["black_friday", "summer"] читается как «black friday, если у этого ключа он есть, иначе summer, иначе по умолчанию». Цепочки также принимаются в месте вызова:

    tsx
    useIntlayer("hero-banner", { variant: ["black_friday", "summer"] });
    Обратите внимание: это зеркальное отражение массива, принимаемого полем variant файла контента: там массив объявляет по одной записи на элемент, здесь он потребляет их в порядке приоритета.

    Отображение по ключам

    Обращайтесь к каждому ключу словаря отдельно. Зарезервированная запись default покрывает все не перечисленные ключи:

    tsx
    <IntlayerProvider  variant={{    "hero-banner": "school1",    product: ["school1", "default"],    default: "base",  }}/>
    На провайдере обычный объект всегда читается как отображение по ключам, но не как объектный вариант — они структурно идентичны. Чтобы задать объектный вариант глобально, вложите его в запись: variant={{ default: { id: "prod_abc" } }}.

    Поскольку ключи отображения сверяются с объявленными ключами словарей, опечатка — или объектный вариант, записанный напрямую, например variant={{ id: "prod_abc" }} — приводит к ошибке компиляции.

    Режим загрузки

    Объектные варианты часто загружаются лениво. Задайте importMode в словаре, чтобы управлять этим:

    ts
    const dictionary = {
      key: "product",
      importMode: "fetch", // or "dynamic"
      variant: { id: "prod_abc", userId: "user_123" },
      content: { … },
    } satisfies Dictionary;
    
    export default dictionary;

    См. оптимизацию бандла для подробностей о режимах static, dynamic и fetch.

    Типичные сценарии использования

    • A/B-тесты текста, управляемые ключом эксперимента
    • Сезонные или рекламные баннеры
    • Сообщения под feature-флагами
    • Маркетинговые кампании для конкретной локали
    • Маркетинговый текст по товарам, управляемый в CMS
    • Контент конкретного пользователя или аккаунта
    • Любой контент, адресуемый непрозрачным ID во время выполнения