An application can change either one without the other: German dates with English labels, or French messages with the locale of the request. The library ships English only.

NameTypeDefaultDescription
Localelocale — Month and weekday names, week start and weekend, date and time layout, numbers and plural rules.
Messagesmessages — The text of the library: accessible names, visible words, placeholders, hints and announcements.

A translation is a typed object that your application owns, or a community package provides. KuiMessages is the contract for it and KUI_ENGLISH_MESSAGES is the complete English pack.

Set the locale and a partial messages layer in the root provider. Only the keys you write change; every other key keeps its English default.

import { provideKikitaUi, type KuiMessagesLayer } from '@kikita-labs/ui';

const german: KuiMessagesLayer = {
  pagination: { next: 'Weiter', previous: 'Zurueck' },
  calendar: { today: 'Heute' },
};

provideKikitaUi({ locale: 'de-DE', messages: german });

A message is a string, or a function with one named parameter object for text that depends on values. A group you leave out stays English.

Pass a Signal or a function. The library re-renders its labels when the signal changes and nothing is recreated.

provideKikitaUi({
  locale: () => inject(LanguageService).locale, // Signal<string>
  messages: () => inject(LanguageService).messages, // Signal<KuiMessagesLayer>
});
  • locale and messages also accept a plain function; it runs in an injection context, so it can inject() services.
  • Angular LOCALE_ID is not read implicitly, because it cannot tell "unset" from en-US. Use the last tab to follow it.

Levels and per-instance inputs let one part of the page differ without affecting another.

booking.component.ts
@Component({
  providers: [
    provideKuiI18n({ locale: 'fr-FR', messages: { calendar: { today: "Aujourd'hui" } } }),
  ],
})
export class BookingComponent {}
  • provideKuiI18n, provideKuiLocale and provideKuiMessages add a level to a component, a route or an environment injector. A level inherits the locale and messages of its parent and changes only what it names; two subtrees never affect each other.
  • Explicit label inputs (ariaLabel, closeLabel, label, swatchLabel, errorLabel, placeholder, emptyText, removeLabel and similar) keep working and win over messages.
  • The messages input exists on the components that own four or more messages: Calendar, Calendar Range, Carousel, the charts, Color Input, Command Palette, Date Picker, File Upload, Pagination and Time Picker. Calendar and Calendar Range also take a locale input.
  • Per-call data does the same for the imperative openers: kuiMediaViewer({ messages }) and kuiConfirm({ confirmLabel, cancelLabel }). For every other component use a subtree level.
  • Precedence: explicit label input, then messages input, then the nearest level, then outer levels, then provideKikitaUi, then English. Merging is per group and per key; undefined inherits and an empty string is a real value.

Copy KUI_ENGLISH_MESSAGES, translate the values and let the compiler check every key.

NameTypeDefaultDescription
ctx.localestring — The resolved locale tag.
ctx.formatNumber(n)string — A number with the grouping and decimal separators of the locale, in Latin digits.
ctx.plural(n, { one, ... })string — The form Intl.PluralRules selects: zero, one, two, few, many or other.
fileUpload: {
  tooMany: ({ max }, { formatNumber, plural }) =>
    `Maksymalnie ${formatNumber(max)} ${plural(max, { one: 'plik', few: 'pliki', many: 'plikow', other: 'pliku' })}`,
},
  • Messages are text only; do not put HTML in them. Text that you pass to a component (titles, option and tab labels, error text, tooltip content, acceptLabel) is yours and is never translated by the library.
  • Messages are plain functions, so any translator fits without a library dependency: wrap it in a function and keep it reactive. This documentation site keeps the Kikita UI messages in its own catalogues and converts them with a short adapter, which is a reference implementation and not a library API.

The locale is resolved from the nearest source and checked against the runtime Intl.

  • Order: Calendar locale input, nearest level, provideKikitaUi({ locale }), then KUI_LOCALE.
  • KUI_LOCALE resolves to the first usable Accept-Language language of the request on the server, hands it to the browser through TransferState so the first client render matches the server HTML, and falls back to navigator.language and then en-US. The host locale is never read on the server.
  • Responses vary by Accept-Language: a cache in front of the server must send Vary: Accept-Language, or pin a locale with provideKuiLocale.
  • A requested tag is canonicalized and checked against the runtime Intl; the fallback chain is the full tag, then language and script, then language, then en-US. Development builds warn once on a fallback. The server needs full ICU data (the default in Node 13 and later), otherwise a locale such as ru-RU can fall back on the server and render differently from the browser.
  • Locale and messages are plain data held per injector, and the formatter caches live in the KuiI18n instance, so one request never sees another. A Signal source that loads asynchronously should resolve before the first render or be provided with the transfer cache.

Each area below follows the resolved locale.

NameTypeDefaultDescription
Calendarlocale — Month and weekday names; heading order; first day and weekend from Intl.Locale getWeekInfo (static fallback for older engines); every day button named with its full date.
Date Pickerlocale — Field order and separator of the numeric date (10/03/2026, 03.10.2026). Parsing reads digit groups and needs a four digit year; format pins a layout.
Time Pickerlocale — Default 12 or 24 hour cycle, the separator, the day period text and its position; typing accepts the locale AM/PM text and ASCII am/pm.
Pagination, Carousel, Media Viewer, OTPlocale — Counts and positions are formatted with the locale.
Chartslocale — The default value format is the compact notation of the locale (1.2K in English, 1,5 Mio. in German).
File Uploadlocale — Sizes use Intl units (2.5 MB, 340 kB) and progress uses a percent format.
  • Dates are formatted in the Gregorian calendar with Latin digits whatever the locale default is, and calendar names are taken from UTC midnight, so the time zone never moves a day.
  • Right-to-left layouts, native non-Latin numerals and non-Gregorian calendars are not supported in 2.0. Text remains translatable in those languages, but layout and digits follow the left-to-right Latin rules.

Accessible names come from the same messages as the visible text.

  • A translation changes visible text and accessible names together, and every name is non-empty by default.
  • The library does not set lang or dir. When the language of the messages differs from the page language, mark the document or the subtree that carries the scope with lang (WCAG 2.2 SC 3.1.2).
  • Calendar day buttons are named with the full localized date and the grid, month and year controls with messages, so a screen reader gets the context a bare day number lacks.
  • To test a translation, wrap every message of the English pack in a marker and render your screens: an accessible name without the marker bypasses the message map.

The public API of the locale and messages layer.

NameTypeDefaultDescription
provideKikitaUi({ locale, messages })Provider — Root locale and messages.
provideKuiI18n({ locale, messages })Provider[] — A level for a subtree.
provideKuiLocale(locale)Provider[] — Locale only. Accepts a tag, a Signal or a function.
provideKuiMessages(messages)Provider[] — Messages only.
KuiI18nservice — locale, messages, context, get(group), setLocale and setMessages.
KuiMessages, KuiMessagesLayertypes — The full message map and its partial override.
KuiMessageContext, KuiPluralFormstypes — Helpers passed to function messages.
KUI_ENGLISH_MESSAGESKuiMessages — The complete English pack.
KUI_LOCALEInjectionToken — Root locale source: request, transfer state, navigator.
getKuiCalendarLocaleText(locale)function — Month and weekday names, first day and weekend for a locale (pure, no cache).