Orchestrator 4.8.0: one build per package, no more stitching.Read the announcement and share your feedback →

I18N

Angular's built-in I18N with Native Federation — how the adapter translates federation artifacts and how to deploy locale-specific remotes.

The Angular adapter supports Angular's built-in internationalization. The federation builder reads the project's i18n block from angular.json and runs localize-translate over the federation artifacts so a single build emits one bundle copy per target locale — alongside Angular's own locale outputs.

Setup

1. Add I18N to every participating project

ng add @angular/localize --project shell
ng add @angular/localize --project mfe1

Both shell and remotes need @angular/localize. Note that @angular/localize is in the adapter's NG_SKIP_LIST — it's deliberately not shared, because it patches globals at boot.

2. Configure I18N in angular.json

{
  "projects": {
    "mfe1": {
      "i18n": {
        "sourceLocale": "en",
        "locales": {
          "de": "src/locale/messages.de.xlf",
          "fr": "src/locale/messages.fr.xlf"
        }
      }
    }
  }
}

Configure I18N in angular.json, never via CLI flags. The federation builder does not forward --localize or --i18n-* flags through to the underlying Application Builder — that's intentional, so the configuration stays declarative.

I18N must be configured in angular.json. CLI flags are not forwarded by design.

3. Federation manifest per locale

In production, point the host's federation.manifest.json at the locale-specific remoteEntry.json:

{
  "mfe1": "https://cdn.example.com/mfe1/de/remoteEntry.json"
}

Each locale's federation output is a self-contained folder — the host serves the right one for the page's language.

What the Builder Does

When the underlying Angular target has localize configured, the builder:

  1. Writes the source-locale federation artifacts to <outputPath>/<browser>/<sourceLocale>/, mirroring Angular's own per-locale layout. <browser> is Angular's outputPath.browser folder — browser by default; with browser: "" the locale folders sit directly under the base.
  2. For every additional locale: creates the locale folder, copies remoteEntry.json into it, and runs localize-translate over every file the federation build wrote, using the translation file declared in i18n.locales.
  3. When the source locale itself is requested (localize: true, or a list that contains it), inlines its $localize calls in place too, as Angular does for the app — including a config with only a sourceLocale. Since 22.2.4.
  4. With integrityHashes on, recomputes the hashes in each locale's remoteEntry.json and importmap.json after translation, so they match the translated files. Since 22.2.4.
  5. Caches the source build so subsequent locales only pay the translation cost.

The output looks like this:

dist/mfe1/browser/
├── en/                    ← sourceLocale (inlined when the source locale is requested)
│   ├── remoteEntry.json
│   ├── _angular_core.<hash>.js
│   └── ...
├── de/                    ← translated copy
│   ├── remoteEntry.json
│   └── ...
└── fr/
    └── ...

Limitations