---
title: "Internationalization and accessibility"
description: "Preserve meaning, direction, keyboard behavior, and assistive relationships."
image: "https://adonia.pages.dev/og.png"
version: "next"
---

> Documentation Index
> Fetch the complete documentation index at: https://adonia.pages.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Internationalization and accessibility

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.

```ts
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:

```tsx
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](/accessibility) 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](/guide/custom-fields). For deployment of locale and cache data, see [Deployment and security](/guide/deployment-security).

Source: https://adonia.pages.dev/guide/i18n-accessibility/index.mdx
