CxJS

Localization

CxJS supports culture-specific number, currency, and date formatting based on Intl helpers provided by modern browsers. It also offers translation of standard widget messages to different languages.

Example

<div>
  <LabelsTopLayout columns={2} controller={PageController}>
    <LookupField
      value={m.culture.id}
      options={m.cultures}
      label="Culture"
      required
    />
    <LookupField
      value={m.currency.id}
      options={m.currencies}
      label="Currency"
      required
    />
  </LabelsTopLayout>
  <ContentResolver
    params={{ culture: m.culture.id, currency: m.currency.id }}
    onResolve={async ({ culture, currency }) => {
      //console.log(culture, currency);
      Culture.setCulture(culture)
      Culture.setDefaultCurrency(currency)

      switch (culture) {
        case "de-de":
          await import("cx/locale/de-de.js")
          break
        case "es-es":
          await import("cx/locale/es-es.js")
          break
        case "fr-fr":
          await import("cx/locale/fr-fr.js")
          break
        default:
          await import("cx/locale/en-us.js")
          break
      }

      return (
        <LabelsTopLayout columns={2} controller={PageController}>
          <NumberField value={m.number} label="Number" />
          <NumberField value={m.number} label="Currency" format="currency" />
          <Calendar value={m.date} label="Date" />
        </LabelsTopLayout>
      )
    }}
  />
</div>
English (US)
USD

Culture

import { Culture } from 'cx/ui'; Copied

The Culture object provides methods for selecting UI cultures used for formatting.

Setting Culture

import "cx/locale/de-de"; // Import locale data

Culture.setCulture("de-de");

Available locale packages include: de-de, en-us, es-es, fr-fr, nl-nl, pt-pt, sr-latn-ba.

Culture Methods

MethodDescription
Culture.setCulture(code)Sets the current culture for all formatting.
Culture.setNumberCulture(code)Sets culture for number formatting only.
Culture.setDateTimeCulture(code)Sets culture for date/time formatting only.
Culture.setDefaultCurrency(code)Sets the default currency (e.g., "EUR", "USD").
Culture.setDefaultTimezone(tz)Sets the default timezone.
Culture.setDefaultDateEncoding(fn)Sets function for encoding dates.

These methods configure the default culture. Call them before the content is rendered: they apply to content rendered after the call, while widgets that already exist may keep the previous settings. If you change settings at runtime, re-render the content afterwards, as shown in Dynamic Culture Loading.

Culture Scopes

To format part of the page with a different culture, timezone or currency, for example to show documents for different timezones side by side, wrap that content in a detached Restate with its own culture created by createCulture:

import { createCulture, enableCultureSensitiveFormatting, Restate, tpl } from "cx/ui";

enableCultureSensitiveFormatting();

<Restate detached culture={createCulture({ timezone: "Asia/Tokyo", defaultCurrency: "JPY" })} data={{ doc: m.doc }}>
  <div text={tpl(m.doc.createdAt, "{0:datetime}")} />
</Restate>;

Each culture created by createCulture has its own format cache. culture, defaultCurrency and dateEncoding are taken from the current culture unless specified; other settings are not. Culture scopes require culture-sensitive formatting, which is enabled automatically by some widgets, such as NumberField.

The culture of a scope is set when the scope is created. To switch it, create a new scope, for example inside a ContentResolver:

<ContentResolver
  params={{ timezone: m.timezone }}
  onResolve={({ timezone }) => (
    <Restate detached culture={createCulture({ timezone })} data={{ doc: m.doc }}>
      ...
    </Restate>
  )}
/>

Dynamic Culture Loading

Use dynamic imports for code-splitting:

async function loadCulture(culture: string) {
  switch (culture) {
    case "de-de":
      await import("cx/locale/de-de");
      break;
    case "fr-fr":
      await import("cx/locale/fr-fr");
      break;
    default:
      await import("cx/locale/en-us");
  }
  Culture.setCulture(culture);
  store.notify(); // Force re-render
}

Localization

import { Localization } from 'cx/ui'; Copied

The Localization object provides methods for translating widget messages.

Localization Methods

MethodDescription
Localization.localize(culture, name, values)Override widget properties for a given culture.
Localization.override(name, values)Override widget properties for all cultures.
Localization.registerPrototype(name, type)Register a component type for localization.

Translating Widget Messages

Localization.localize("de", "cx/widgets/TextField", {
  validationErrorText: "Ungültige Eingabe.",
  minLengthValidationErrorText: "Mindestens {0} Zeichen erforderlich.",
  maxLengthValidationErrorText: "Maximal {0} Zeichen erlaubt.",
});

Overriding Defaults

Use override to change defaults for all cultures:

Localization.override("cx/widgets/DateField", {
  format: "dd.MM.yyyy",
});