CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-react-i18next

React integration for i18next internationalization framework with hooks, components, and SSR support

Pending
Overview
Eval results
Files

icu-macro.mddocs/

ICU Message Format Support

React i18next provides compile-time ICU message format support through Babel macros, offering both template literal functions and React components for pluralization, selection, and formatting.

Package Import

import { Plural, Select, plural, select, date, time, number } from "react-i18next/icu.macro";

Capabilities

Template Literal Functions

Compile-time template literal functions that transform ICU syntax into i18next-compatible translations.

/**
 * Date formatting with ICU syntax (compile-time transformation)
 * @param strings - Template string array
 * @param variable - Date value to format
 * @returns Formatted date string
 */
function date(strings: TemplateStringsArray, variable: Date): string;

/**
 * Time formatting with ICU syntax (compile-time transformation)
 * @param strings - Template string array  
 * @param variable - Date value to format time from
 * @returns Formatted time string
 */
function time(strings: TemplateStringsArray, variable: Date): string;

/**
 * Number formatting with ICU syntax (compile-time transformation)
 * @param strings - Template string array
 * @param variable - Number value to format
 * @returns Formatted number string
 */
function number(strings: TemplateStringsArray, variable: number): string;

/**
 * Pluralization with ICU syntax (compile-time transformation)
 * @param strings - Template string array with plural forms
 * @param variable - Count value for pluralization
 * @param args - Additional interpolation values
 * @returns Pluralized string
 */
function plural(
  strings: TemplateStringsArray,
  variable: number,
  ...args: ValidInterpolations[]
): string;

/**
 * Ordinal selection with ICU syntax (compile-time transformation)
 * @param strings - Template string array with ordinal forms
 * @param variable - Number value for ordinal selection
 * @param args - Additional interpolation values
 * @returns Ordinal string
 */
function selectOrdinal(
  strings: TemplateStringsArray,
  variable: number,
  ...args: ValidInterpolations[]
): string;

/**
 * Value selection with ICU syntax (compile-time transformation)
 * @param strings - Template string array with selection options
 * @param variable - String value for selection
 * @param args - Additional interpolation values
 * @returns Selected string
 */
function select(
  strings: TemplateStringsArray,
  variable: string,
  ...args: ValidInterpolations[]
): string;

type ValidInterpolations = React.ReactElement | string;

Usage Examples:

import { plural, select, date, time, number } from "react-i18next/icu.macro";

// Pluralization
function ItemCounter({ count }) {
  const message = plural`You have ${count} {count, plural, 
    =0 {no items}
    one {# item}
    other {# items}
  }`;
  
  return <p>{message}</p>;
}

// Selection
function GenderGreeting({ person }) {
  const greeting = select`Hello ${person.name}, {${person.gender}, select,
    male {Mr. ${person.name}}
    female {Ms. ${person.name}}
    other {${person.name}}
  }`;
  
  return <span>{greeting}</span>;
}

// Date formatting
function EventDate({ event }) {
  const formatted = date`Event date: ${event.date}`;
  return <time>{formatted}</time>;
}

// Time formatting
function CurrentTime({ now }) {
  const timeStr = time`Current time: ${now}`;
  return <span>{timeStr}</span>;
}

// Number formatting
function Price({ amount }) {
  const price = number`Price: ${amount}`;
  return <span className="price">{price}</span>;
}

// Ordinal numbers
function Position({ rank }) {
  const position = selectOrdinal`You finished ${rank} {${rank}, selectordinal,
    one {#st}
    two {#nd}  
    few {#rd}
    other {#th}
  }`;
  
  return <div>{position}</div>;
}

// Complex example with multiple interpolations
function OrderStatus({ order, customer }) {
  const status = plural`Order for ${customer} has ${order.itemCount} {${order.itemCount}, plural,
    =0 {no items}
    one {# item}
    other {# items}  
  } and costs ${number`${order.total}`}`;
  
  return <p>{status}</p>;
}

React Components

React components providing runtime ICU message format support without compile-time transformation.

/**
 * Pluralization component with props-based configuration
 * @param props - Plural component properties
 */
function Plural<
  T,
  Key extends ParseKeys<Ns, {}, ''>,
  Ns extends Namespace = TypeOptions['defaultNS']
>(props: PluralProps<T, Key, Ns> & NoChildren): ReactElement;

/**
 * Ordinal selection component with props-based configuration  
 * @param props - SelectOrdinal component properties
 */
function SelectOrdinal<
  T,
  Key extends ParseKeys<Ns, {}, ''>,
  Ns extends Namespace = TypeOptions['defaultNS']
>(props: PluralProps<T, Key, Ns> & NoChildren): ReactElement;

/**
 * Value selection component with props-based configuration
 * @param props - Select component properties
 */
function Select<
  Key extends ParseKeys<Ns, {}, ''>,
  Ns extends Namespace = TypeOptions['defaultNS']
>(props: SelectProps<Key, Ns>): ReactElement;

// Component prop interfaces
interface PluralSubProps<Key, Ns> {
  children?: never;
  i18nKey?: Key;
  i18n?: i18n;
  ns?: Ns;
  count: number;
  values?: {};
  zero?: string | ReactElement;
  one?: string | ReactElement;
  two?: string | ReactElement;
  few?: string | ReactElement;
  many?: string | ReactElement;
  other: string | ReactElement; // Required
}

type PluralProps<T, Key, Ns> = {
  [P in keyof T]: P extends keyof PluralSubProps<Key, Ns>
    ? PluralSubProps<Key, Ns>[P]
    : P extends `$${number}`
      ? string | ReactElement
      : never;
};

interface SelectProps<Key, Ns> {
  [key: string]: string | ReactElement;
  i18nKey?: Key;
  i18n?: i18n;
  ns?: Ns;
  other: string | ReactElement; // Required
  children?: never;
}

interface NoChildren {
  children?: never;
}

Usage Examples:

import { Plural, Select, SelectOrdinal } from "react-i18next/icu.macro";

// Plural component
function MessageCount({ count }) {
  return (
    <Plural
      i18nKey="messageCount"
      count={count}
      zero="No messages"
      one="One message"
      other="{{count}} messages"
    />
  );
}

// Select component  
function UserRole({ user }) {
  return (
    <Select
      i18nKey="userGreeting"
      role={user.role}
      admin="Welcome, Administrator!"
      user="Hello, User!"
      guest="Welcome, Guest!"
      other="Welcome!"
    />
  );
}

// SelectOrdinal component
function RankDisplay({ position }) {
  return (
    <SelectOrdinal
      i18nKey="ranking"
      count={position}
      one="{{count}}st place"
      two="{{count}}nd place"  
      few="{{count}}rd place"
      other="{{count}}th place"
    />
  );
}

// Complex plural with custom values
function OrderSummary({ order }) {
  return (
    <div>
      <Plural
        i18nKey="orderItems"
        count={order.items.length}
        values={{ 
          customerName: order.customer,
          orderDate: order.date
        }}
        zero="Order for {{customerName}} on {{orderDate}} has no items"
        one="Order for {{customerName}} on {{orderDate}} has {{count}} item"
        other="Order for {{customerName}} on {{orderDate}} has {{count}} items"
      />
    </div>
  );
}

// Dynamic select options
function StatusBadge({ status, options }) {
  const selectProps = {
    i18nKey: "status",
    status: status,
    other: "Unknown status",
    ...options // Dynamic options like { active: "Active", inactive: "Inactive" }
  };
  
  return <Select {...selectProps} />;
}

// With namespace
function LocalizedPlural({ count }) {
  return (
    <Plural
      ns="commerce"
      i18nKey="cartItems"
      count={count}
      zero="Empty cart"
      one="{{count}} item in cart"
      other="{{count}} items in cart"
    />
  );
}

Runtime Fallback Functions

Dummy functions exported from main package for runtime fallback when macros aren't processed.

/**
 * Runtime fallback functions (return empty strings when macros not processed)
 * Available from main react-i18next import
 */
const date: () => string;
const time: () => string;
const number: () => string;
const select: () => string;
const plural: () => string;
const selectOrdinal: () => string;

Usage Examples:

import { date, time, number, plural } from "react-i18next";

// These return empty strings at runtime if macros aren't processed
function Fallbacks() {
  return (
    <div>
      <p>{date()}</p>        {/* Returns "" */}
      <p>{time()}</p>        {/* Returns "" */}
      <p>{number()}</p>      {/* Returns "" */}
      <p>{plural()}</p>      {/* Returns "" */}
    </div>
  );
}

Babel Configuration

The ICU macro requires Babel configuration to process template literals at compile time:

// babel.config.js
module.exports = {
  plugins: [
    'macros', // or 'babel-plugin-macros'
  ],
};

// .babelrc
{
  "plugins": ["macros"]
}

Translation File Generation

ICU macros can generate corresponding translation files:

// Source code with ICU macro
const message = plural`You have ${count} {count, plural,
  =0 {no items}
  one {# item}
  other {# items}
}`;

// Generated translation entry
{
  "generated_plural_key": "You have {{count}} {{count, plural, =0{no items} one{# item} other{# items}}}"
}

Advanced Usage

Mixed ICU and i18next

import { useTranslation } from "react-i18next";
import { plural, select } from "react-i18next/icu.macro";

function MixedExample({ user, itemCount }) {
  const { t } = useTranslation();
  
  // Regular i18next
  const welcome = t('welcome', { name: user.name });
  
  // ICU macro
  const items = plural`You have ${itemCount} {${itemCount}, plural,
    =0 {no items}
    one {# item}
    other {# items}
  }`;
  
  const greeting = select`{${user.type}, select,
    premium {Welcome, Premium Member!}
    standard {Hello, Member!}
    other {Welcome!}
  }`;
  
  return (
    <div>
      <h1>{welcome}</h1>
      <p>{greeting}</p>
      <p>{items}</p>
    </div>
  );
}

Conditional ICU Usage

// Feature detection for ICU support
const hasICUSupport = typeof Intl !== 'undefined' && Intl.PluralRules;

function AdaptiveComponent({ count }) {
  if (hasICUSupport) {
    return (
      <Plural
        count={count}
        zero="No items"
        one="One item"
        other="{{count}} items"
      />
    );
  }
  
  // Fallback to simple conditional
  const { t } = useTranslation();
  return <span>{t('itemCount', { count })}</span>;
}

Type Safety

// Type definitions for ICU macro components
type ICUInterpolation = string | React.ReactElement;

interface ICUPluralForms {
  zero?: ICUInterpolation;
  one?: ICUInterpolation;
  two?: ICUInterpolation;
  few?: ICUInterpolation;
  many?: ICUInterpolation;
  other: ICUInterpolation; // Always required
}

interface ICUSelectOptions {
  [key: string]: ICUInterpolation;
  other: ICUInterpolation; // Always required
}

The ICU macro system provides both compile-time optimization through Babel transformation and runtime components for dynamic ICU message format support in React applications.

Install with Tessl CLI

npx tessl i tessl/npm-react-i18next

docs

components.md

hocs.md

hooks.md

icu-macro.md

index.md

ssr.md

tile.json