Skip to main content

Internationalization (i18n)

The Fanfare SDK includes built-in internationalization support for all UI text.

Supported Locales

type Locale =
  | "en" // English (default)
  | "es" // Spanish
  | "fr" // French
  | "de" // German
  | "it" // Italian
  | "pt" // Portuguese
  | "ja" // Japanese
  | "ko" // Korean
  | "zh"; // Chinese

Setting the Locale

Provider Level

import { FanfareProvider } from "@waitify-io/fanfare-sdk-react";

function App() {
  return (
    <FanfareProvider organizationId="org_xxx" publishableKey="pk_live_xxx" locale="es">
      <YourApp />
    </FanfareProvider>
  );
}

Web Components

registerWebComponents({
  organizationId: "org_xxx",
  publishableKey: "pk_live_xxx",
  locale: "fr",
});

Custom Translations

Override default translations with custom text:
<FanfareProvider
  organizationId="org_xxx"
  publishableKey="pk_live_xxx"
  locale="en"
  translations={{
    "queue.enter": "Join the Line",
    "queue.leave": "Leave the Line",
    "queue.position": "Your place: {{position}}",
    "admitted.title": "You're In!",
    "admitted.cta": "Start Shopping",
    "draw.enter": "Enter the Raffle",
    "draw.withdraw": "Remove Entry",
    "auction.placeBid": "Place Your Bid",
    "auction.winning": "Highest Bidder!",
    "auction.outbid": "You've Been Outbid",
  }}
>
  <YourApp />
</FanfareProvider>

Translation Keys

Queue Keys

KeyDefault (English)
queue.enterEnter Queue
queue.leaveLeave Queue
queue.positionPosition:
queue.estimatedWaitEstimated wait:
queue.admittedYou have been admitted!
queue.expiredYour admission has expired

Draw Keys

KeyDefault (English)
draw.enterEnter Draw
draw.withdrawWithdraw Entry
draw.enteredYou are entered!
draw.countdownDraw in
draw.wonCongratulations! You won!
draw.lostBetter luck next time

Auction Keys

KeyDefault (English)
auction.enterJoin Auction
auction.placeBidPlace Bid
auction.currentBidCurrent bid
auction.minBidMinimum bid
auction.winningYou are winning!
auction.outbidYou have been outbid
auction.wonAuction won!
auction.lostAuction ended
auction.timeRemainingTime remaining

General Keys

KeyDefault (English)
common.loadingLoading…
common.errorAn error occurred
common.retryTry Again
common.continueContinue
common.cancelCancel
admitted.ctaContinue to Checkout

Using Translations in Components

useTranslations Hook

import { useTranslations } from "@waitify-io/fanfare-sdk-react";

function MyComponent() {
  const t = useTranslations();

  return (
    <div>
      <h1>{t("queue.admitted")}</h1>
      <p>{t("queue.position", { position: 42 })}</p>
      <button>{t("admitted.cta")}</button>
    </div>
  );
}

Interpolation

Translations support variable interpolation:
// Translation: "Position: {{position}} of {{total}}"
t("queue.positionOf", { position: 5, total: 100 });
// Result: "Position: 5 of 100"

// Translation: "Estimated wait: {{time}}"
t("queue.estimatedWait", { time: "5 minutes" });
// Result: "Estimated wait: 5 minutes"

Dynamic Locale Switching

import { useState } from "react";
import { FanfareProvider, type Locale } from "@waitify-io/fanfare-sdk-react";

function App() {
  const [locale, setLocale] = useState<Locale>("en");

  return (
    <FanfareProvider organizationId="org_xxx" publishableKey="pk_live_xxx" locale={locale}>
      <select value={locale} onChange={(e) => setLocale(e.target.value as Locale)}>
        <option value="en">English</option>
        <option value="es">Español</option>
        <option value="fr">Français</option>
        <option value="de">Deutsch</option>
      </select>
      <YourApp />
    </FanfareProvider>
  );
}

RTL Support

The SDK automatically handles right-to-left languages:
const RTL_LOCALES = ["ar", "he", "fa", "ur"];

// Check if current locale is RTL
import { isRTLLocale } from "@waitify-io/fanfare-sdk-react";

if (isRTLLocale(locale)) {
  document.documentElement.dir = "rtl";
}

Experience-Level Translations

Translations can be configured per-experience in the Fanfare dashboard. These are automatically loaded when using useExperienceJourney:
function ExperiencePage({ experienceId }: { experienceId: string }) {
  // Experience-level i18n is automatically loaded
  const { status } = useExperienceJourney(experienceId, { autoStart: true });

  // Translations from the experience are now available
  const t = useTranslations();

  return <div>{t("custom.experienceTitle")}</div>;
}

Merging Translations

import { mergeTranslations, en } from "@waitify-io/fanfare-sdk-react";

const customTranslations = mergeTranslations(en, {
  "queue.enter": "Get in Line",
  "custom.myKey": "My custom text",
});

TypeScript

import type {
  Locale,
  TranslationKey,
  TranslationMessages,
  PartialTranslationMessages,
} from "@waitify-io/fanfare-sdk-react";

const myTranslations: PartialTranslationMessages = {
  "queue.enter": "Join Queue",
};