OGE logoOGE

Localization

Every user-facing string — empty states, aria labels, validation errors, tooltips — lives in a typed message catalog. Nothing is hardcoded: provide a catalog once for the whole application, or override single strings per component instance.

messages provideOge…Config [messages] locale

How it works

Each package exports a messages interface (for example OgeGridMessages, OgeInputsMessages). Catalogs are partial — you only supply the strings you change, the rest keep their English defaults. Patterns support {placeholder} interpolation for dynamic values.

The catalogs themselves are shared. Message names, defaults and placeholder syntax live in the framework-free packages, so a translation written once is correct in both render layers. Only the delivery differs: Angular takes a provideOge…Config() provider, React an <Oge…ConfigProvider> — the same object, handed over the way each framework expects.

Global configuration

import { provideOgeGridConfig } from '@oge-ui/grid';
import { provideOgeInputsConfig } from '@oge-ui/inputs';
import { provideOgeButtonsConfig } from '@oge-ui/buttons';

// app.config.ts — a Turkish application
providers: [
  provideOgeGridConfig({
    messages: {
      noData: 'Kayıt bulunamadı',
      search: 'Ara…',
      rowsSuffix: 'satır',
      summaryLabels: { sum: 'Toplam', avg: 'Ort', min: 'Min', max: 'Maks', count: 'Adet' },
    },
  }),
  provideOgeInputsConfig({
    messages: {
      requiredError: 'Bu alan zorunludur',
      clearButton: 'Temizle',
      counterAria: '{max} karakterden {count} tanesi kullanıldı',
    },
  }),
  provideOgeButtonsConfig({
    messages: { loading: 'Yükleniyor', holdToConfirm: 'Onaylamak için basılı tutun' },
  }),
]

Switching language at runtime

Every provideOge…Config() also accepts a function. The config then follows the signals that function reads: flip your language signal and every OGE component re-renders its strings — and, with locale, its number and date formats — without reloading the page or fetching the catalog before bootstrap. A component-level [messages] input still wins over it. In React, pass a new config to the <Oge…ConfigProvider>; context already re-renders.

import { signal } from '@angular/core';
import { provideOgeGridConfig } from '@oge-ui/grid';
import { provideOgeInputsConfig } from '@oge-ui/inputs';
import { GRID_TR, INPUTS_TR } from './i18n/tr';

/** The app's own language state — a cookie, a store, a user setting… */
export const uiLanguage = signal<'en' | 'tr'>('en');

// Pass a function instead of an object: the config becomes live. Every OGE
// component re-renders its strings when a signal the function reads changes —
// no reload, no re-bootstrap. English is the built-in default, so '{}' is enough.
export const appConfig = {
  providers: [
    provideOgeGridConfig(() => ({
      messages: uiLanguage() === 'tr' ? GRID_TR : {},
    })),
    provideOgeInputsConfig(() => ({
      messages: uiLanguage() === 'tr' ? INPUTS_TR : {},
      locale: uiLanguage() === 'tr' ? 'tr-TR' : 'en-US', // Intl formats follow too
    })),
  ],
};

// anywhere: uiLanguage.set('tr');

Per-component overrides

Components accept the same catalog through a [messages] input. Instance values win over the global provider, which wins over the built-in defaults:

<!-- the [messages] input overrides the global catalog for one instance -->
<oge-grid [data]="rows" [messages]="{ noData: 'No matching orders' }" />

<oge-text-box
  label="Coupon code"
  [messages]="{ requiredError: 'Enter a coupon to continue' }"
/>

Validation messages

Input editors resolve validation errors from the catalog — the same strings serve standalone validation, reactive forms and Signal Forms, so translating them once covers all three binding modes:

// Message patterns interpolate the constraint that failed:
provideOgeInputsConfig({
  messages: {
    minError: 'Value must be at least {min}',
    maxLengthError: 'Enter no more than {requiredLength} characters',
  },
})

// Priority when an editor resolves its error text:
// 1. errorText input          (always wins when set)
// 2. parse errors             (e.g. invalid number)
// 3. form errors              (Signal Forms / reactive), mapped through the catalog

Number & date locales

Formatting is separate from message catalogs: number editors format and parse through Intl.NumberFormat, honoring an explicit locale input or Angular's LOCALE_ID. Grouped input like 1.234,56 parses correctly in every locale:

<!-- Intl-powered: grouping, decimal separator and currency follow the locale -->
<oge-number-box
  label="Price"
  locale="de-DE"
  [format]="{ style: 'currency', currency: 'EUR' }"
/>

<!-- without an explicit locale, editors use Angular's LOCALE_ID -->

Behavior defaults

The config providers also centralize timing and interaction defaults, so product-wide tuning does not require touching templates:

// The same providers also carry non-text defaults:
provideOgeButtonsConfig({
  clickGuardMs: 300,       // default clickGuard window
  holdToConfirmMs: 1000,   // default hold duration
}),
provideOgeInputsConfig({
  spinRepeatDelayMs: 300,  // number-box spin: delay before repeating
  spinRepeatIntervalMs: 60,
  copiedResetMs: 1500,     // "copied" indicator duration
})