---
title: Internationalization
description: HTML locale variants, localized attributes and component-owned morphing.
---

# Internationalization

`defuss-i18n` shares defuss-shadcn's query/morph runtime. Keep immutable locale sources in ordinary HTML templates, translate content attributes declaratively and preserve state by owning explicit regions.

## Demo

Run `bun run serve` and open `/docs/`. The project site is built from defuss-shadcn blocks (floating site header, parallax hero, Code Mockup with tabs and a diff, features, process steps, cards in a window frame, stats, tabs with code blocks, CTA, footer) and loads defuss-shadcn 0.9.8 and defuss-i18n 0.1.0 from jsDelivr. It shows English and German, plural templates (one egg, two eggs; ein Ei, zwei Eier), localized images and attributes, a modal dialog with an edited input, an explicit state renderer and a live log of `defuss-i18n:change` events.

## Markup

```html
<section id="greeting" data-i18n-component>
  <h2 data-i18n-target="heading">Welcome</h2>
  <template data-i18n-for="heading" data-i18n-locale="en">Welcome</template>
  <template data-i18n-for="heading" data-i18n-locale="de">Willkommen</template>
  <button aria-label="Close" data-i18n-aria-label-en="Close"
          data-i18n-aria-label-de="Schließen">×</button>
</section>
```

## Wiring

Load shadcn core, then the i18n module, in this order:

```html
<script type="module">
  await import('https://cdn.jsdelivr.net/npm/defuss-shadcn@0.9.8/dist/components/core.min.js');
  await import('https://cdn.jsdelivr.net/npm/defuss-i18n@0.1.0/dist/all.min.js');
  const locale = df$.i18n.createI18n({ locale: 'en', fallback: ['en'] });
  const component = df$.i18n.bind(document.getElementById('greeting'), locale);
  locale.setLocale('de');
</script>
```

With a bundler, import `createI18n`/`bindI18n` from `defuss-i18n`. Dispose bindings/controllers explicitly on unmount.

## State and accessibility

Targets own complete descendant markup. Keep modal/popover shells, initialization and nested component state outside targets. Preserve semantic IDs/stable keys. Translate accessible content labels; preserve ARIA state and ID references. Root lang/dir reflects requested locale; fallback regions reflect the actual language rendered.

Use `[data-i18n-value]` for literal values and `[data-i18n-count]` with plural categories for quantities. Missing values, unsupported coverage and ownership violations produce actionable errors. Complete state renderers are optional; use afterRender for explicit checked/value property control.

Continue with [getting started](getting-started.md), [state and ownership](state-and-ownership.md), [lazy loading](lazy-loading.md), [security](security.md), the [API reference](api.md) and [errors and diagnostics](errors.md). The [authoring contract](component-skill.md) condenses the rules. Run `bun run check` before release. Tests exercise actual distributions and real defuss peers, including modal/focus/input preservation.
