NEURALNG
FOUNDATION

Localization

Switch component messages, locale conventions and writing direction at runtime through one tree-shakable Signal contract.

Runtime SignalsEnglish fallbackSSR deterministic

APPLICATION SETUP

Configure the initial locale

Pass the initial locale to provideNeuralNg(). English is built in; additional locale packs use granular entry points, so only explicitly imported languages enter the application bundle.

app.config.ts TypeScript
import { ApplicationConfig } from '@angular/core';
import { provideNeuralNg } from '@neural-ng/core';
import { neuralTr } from '@neural-ng/core/locales/tr';

export const appConfig: ApplicationConfig = {
  providers: [
    provideNeuralNg({
      locale: neuralTr,
      direction: 'auto',
    }),
  ],
};
EN

English

@neural-ng/core/locales/en
TR

Türkçe

@neural-ng/core/locales/tr
DE

Deutsch

@neural-ng/core/locales/de
FR

Français

@neural-ng/core/locales/fr
ES

Español

@neural-ng/core/locales/es
PT

Português (Brasil)

@neural-ng/core/locales/pt-br
AR

العربية

@neural-ng/core/locales/ar
ZH

简体中文

@neural-ng/core/locales/zh-cn

All eight packs fully implement the current message contract. Each is an independent secondary entry point; importing one never bundles the others. Build additional languages with the custom-locale contract below.

Switch language without reloading

The demo below changes the real global locale service. Its Paginator, accessible labels and range report update from the same locale state. The original site locale is restored when you leave this page.

Active locale

en-US

Direction
ltr
First day of week
0
Resolved report
Showing 1 to 10 of 137 items
language-picker.ts TypeScript
import { Component, inject } from '@angular/core';
import { NeuralLocaleService } from '@neural-ng/core/i18n';
import { neuralEn } from '@neural-ng/core/locales/en';
import { neuralTr } from '@neural-ng/core/locales/tr';
import { neuralAr } from '@neural-ng/core/locales/ar';

@Component({
  selector: 'app-language-picker',
  template: `
    <button type="button" (click)="locale.use(neuralEn)">English</button>
    <button type="button" (click)="locale.use(neuralTr)">Türkçe</button>
    <button type="button" (click)="locale.use(neuralAr)">العربية</button>
  `,
})
export class LanguagePicker {
  readonly locale = inject(NeuralLocaleService);
  readonly neuralEn = neuralEn;
  readonly neuralTr = neuralTr;
  readonly neuralAr = neuralAr;
}

Read resolved locale Signals

Components consume readonly Signals rather than copying locale state. Message interpolation is plain text and preserves unknown placeholders.

locale-state.ts TypeScript
readonly locale = inject(NeuralLocaleService);

// All values update reactively after locale.use(...)
this.locale.locale();    // NeuralResolvedLocale
this.locale.code();      // "en-US" | "tr-TR" | ...
this.locale.direction(); // "ltr" | "rtl"
this.locale.messages();  // Fully resolved message groups

this.locale.format(
  this.locale.messages().paginator.report,
  { start: 1, end: 10, total: 137 },
);

Create a partial custom locale

A locale needs a canonical language tag and direction. Message groups are partial: define only product-specific translations while every missing entry resolves from the English baseline.

ar-SA.locale.ts TypeScript
import type { NeuralLocale } from '@neural-ng/core/i18n';

export const productArabic: NeuralLocale = {
  code: 'ar-SA',
  direction: 'rtl',
  firstDayOfWeek: 0,
  messages: {
    common: {
      clear: 'مسح',
      close: 'إغلاق',
    },
    paginator: {
      nextPage: 'الصفحة التالية',
      previousPage: 'الصفحة السابقة',
    },
  },
};

Locale messages are text-only. Never place HTML, scripts or template markup inside translations.

Fallback and precedence

Resolution is deterministic. The nearest explicit component label wins, followed by the active locale and finally the complete English fallback.

01

Component override

A local labels or locale input for one instance.

02

Active locale

The current NeuralLocaleService message.

03

English fallback

The built-in value for every missing message.

results.html HTML
<neural-paginator
  [totalItems]="137"
  [labels]="{
    navigation: 'Search result pages',
    nextPage: 'Show newer results'
  }"
/>

Locale direction and document direction

A locale exposes ltr or rtl, but the locale service alone does not mutate the document. Configure provideNeuralNg({ direction: 'auto' }) to let NeuralNgService follow the active locale and apply the native html[dir] contract. Explicit ltr or rtl configuration always wins.

Format dates and numbers with Intl

Use the resolved locale code with browser-native Intl formatters. DatePicker uses the same locale contract for month/day names, field order and first-day-of-week behavior, while its parser remains strict and deterministic.

formatting.ts TypeScript
const currency = new Intl.NumberFormat(locale.code(), {
  style: 'currency',
  currency: 'TRY',
}).format(1250);

const month = new Intl.DateTimeFormat(locale.code(), {
  month: 'long',
  year: 'numeric',
}).format(new Date(2026, 7, 1));

SSR and hydration must start identically

Configure the same initial locale on server and browser. NeuralNg does not read navigator.language during rendering because an environment-dependent default can produce different text, direction and calendar structure during hydration.