Skip to content

Internationalization and accessibility

Preserve meaning, direction, keyboard behavior, and assistive relationships.

Localization and accessibility are one contract: translated copy must retain names, descriptions, error relationships, live announcements, keyboard behavior, focus order, and usable layout in both directions.

Server catalog and optional AdonisJS i18n

Adonia bundles a complete English catalog in @adonia/core/i18n. The server adapter reads the optional @adonisjs/i18n HttpContext macro structurally, so it is not a hard runtime dependency. Host keys use the adonia. prefix.

import {
  createHttpContextTranslator,
  type TranslationMessages,
} from '@adonia/core/i18n'
import type { HttpContext } from '@adonisjs/core/http'

export function panelLocale(ctx: HttpContext) {
  return createHttpContextTranslator(ctx)
}

export const frenchOverrides: TranslationMessages = {
  'action.cancel': 'Annuler',
  'action.save': 'Enregistrer',
}

createHttpContextTranslator(ctx) returns locale, derived direction, a complete browser-safe messages catalog, and t. Locale resolution prefers ctx.i18n.locale, then the first Accept-Language value, then en. A missing adapter, locale, or key falls back to bundled English. Framework keys are closed and type-checked; resource, field, action, and tenant labels remain host-owned.

Descriptor caches are partitioned by locale. Do not reuse a descriptor or page envelope across locale identities in application caches.

Client provider and hooks

The panel envelope supplies locale, messages, and direction to the UI provider. Custom components can use the same hooks:

import { useDirection, useLocale, useTranslation } from '@adonia/ui'

export function LocalizedStatus() {
  const t = useTranslation()
  const locale = useLocale()
  const direction = useDirection()

  return (
    <output lang={locale} dir={direction}>
      {t('action.completed')}
    </output>
  )
}

AdoniaI18nProvider defaults to English and ltr, completes partial messages with English fallback, and synchronizes document lang and dir in the browser while remaining SSR-safe. Use translateMessage for non-component client helpers. Never create a second fallback catalog in a plugin.

Pseudo-locale and RTL

PSEUDO_LOCALE is en-XA; pseudoTranslations() expands and marks every English value while preserving interpolation tokens. directionForLocale() recognizes RTL language tags. Pseudo-localization exposes clipping and untranslated literals; RTL exercises logical layout, focus flow, tables, forms, menus, and icons. Neither is evidence of a manual screen-reader review.

Accessibility obligations

Adonia targets WCAG 2.2 AA. Custom and plugin components must:

  • expose a programmatic name and description;
  • connect errors and required state to their controls;
  • remain keyboard reachable with visible focus;
  • preserve focus trapping/restoration and Escape behavior in overlays;
  • announce asynchronous status without stealing focus;
  • use real table, form, heading, and button semantics;
  • honor reduced motion and both ltr and rtl;
  • keep touch targets and contrast usable at zoom and narrow widths.

The factual accessibility conformance report links claims to executable test ids and distinguishes automation from manual observation. Do not treat lang: en-US in the documentation site, an axe-only result, or compiled snippets as runtime panel conformance.

For custom renderers, also follow Custom fields end to end. For deployment of locale and cache data, see Deployment and security.

Navigation

Type to search…

↑↓ navigate↵ selectEsc close