作者:
    Creation:2026-06-12Last update:2026-06-26

    变体

    变体是一组共享相同字典 key、但各自携带不同 variant 值的内容文件。Intlayer 根据传递给 useIntlayer 的选择器提供相应的文件。

    variant 的值可以采用两种形式

    • 字符串 — 单个具名替代项(A/B 测试、季节性横幅、功能开关)。
    • 对象 — 由一组字段寻址的结构化判别器(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.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" } });

    加载模式

    对象变体通常被惰性加载。在字典上设置 importMode 以控制此行为:

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

    有关 staticdynamicfetch 模式的详细信息,请参阅包优化

    典型用例

    • 由实验键驱动的 A/B 文案测试
    • 季节性或促销横幅
    • 功能开关消息
    • 特定语言环境的营销活动
    • 在 CMS 中管理的按产品营销文案
    • 用户特定或账户特定的内容
    • 在运行时以不透明 ID 作为键的任何内容