Which @angular/* package(s) are the source of the bug?
Is this a regression?
No
Description
When an SSR application uses @angular/localize's runtime loadTranslations() to switch locales per incoming request, every request renders with the English source strings regardless of which translation map was loaded. The behavior reproduces with a stock npm create @angular --ssr app on Angular 21.2.7 — no third-party framework involved.
The repro's Express middleware loads the correct translation map before every AngularNodeAppEngine.handle(req) call:
app.use((req, res, next) => {
const locale = detectLocale(req.url);
clearTranslations();
loadTranslations(translations[locale]);
angularApp.handle(req).then(...);
});
Each request correctly populates globalThis.$localize.TRANSLATIONS before the render starts — but the rendered HTML for every URL returns the English source strings as if loadTranslations had never been called.
Expected: either runtime loadTranslations() works for per-request SSR locale switching and this repro returns localized text for each URL, or the docs for loadTranslations explicitly call out that this workflow is not supported and point to build-time --localize as the only path for multi-locale SSR.
Actual: every URL returns English source text.
Reproduction steps
git clone https://github.com/brandonroberts/angular-i18n-ssr-repro
cd angular-i18n-ssr-repro
npm install
npm run build
node dist/angular-i18n/server/server.mjs
In another terminal:
curl -s http://localhost:4000/fr | grep -oE 'Hello|Bonjour|Hallo'
# → "Hello" (expected: "Bonjour")
curl -s http://localhost:4000/de | grep -oE 'Hello|Bonjour|Hallo'
# → "Hello" (expected: "Hallo")
curl -s http://localhost:4000/en | grep -oE 'Hello|Bonjour|Hallo'
# → "Hello" (expected)
Minimal reproduction
https://github.com/brandonroberts/angular-i18n-ssr-repro
Exception or error
None. Silent fall-through — no warnings or errors are emitted.
Environment (ng version)
Angular CLI : 21.2.7
Angular : 21.2.9
Node.js : 24.14.1
Package Manager : npm 11.11.0
Operating System : darwin arm64
Package | Installed Version | Requested Version
--------------------------+-------------------+------------------
@angular/build | 21.2.7 | ^21.2.7
@angular/cli | 21.2.7 | ^21.2.7
@angular/common | 21.2.9 | ^21.2.0
@angular/compiler | 21.2.9 | ^21.2.0
@angular/compiler-cli | 21.2.9 | ^21.2.0
@angular/core | 21.2.9 | ^21.2.0
@angular/forms | 21.2.9 | ^21.2.0
@angular/localize | 21.2.9 | ^21.2.9
@angular/platform-browser | 21.2.9 | ^21.2.0
@angular/platform-server | 21.2.9 | ^21.2.0
@angular/router | 21.2.9 | ^21.2.0
@angular/ssr | 21.2.7 | ^21.2.7
rxjs | 7.8.2 | ~7.8.0
typescript | 5.9.3 | ~5.9.2
Which @angular/* package(s) are the source of the bug?
localizeplatform-serverIs this a regression?
No
Description
When an SSR application uses
@angular/localize's runtimeloadTranslations()to switch locales per incoming request, every request renders with the English source strings regardless of which translation map was loaded. The behavior reproduces with a stocknpm create @angular --ssrapp on Angular 21.2.7 — no third-party framework involved.The repro's Express middleware loads the correct translation map before every
AngularNodeAppEngine.handle(req)call:Each request correctly populates
globalThis.$localize.TRANSLATIONSbefore the render starts — but the rendered HTML for every URL returns the English source strings as ifloadTranslationshad never been called.Expected: either runtime
loadTranslations()works for per-request SSR locale switching and this repro returns localized text for each URL, or the docs forloadTranslationsexplicitly call out that this workflow is not supported and point to build-time--localizeas the only path for multi-locale SSR.Actual: every URL returns English source text.
Reproduction steps
git clone https://github.com/brandonroberts/angular-i18n-ssr-repro cd angular-i18n-ssr-repro npm install npm run build node dist/angular-i18n/server/server.mjsIn another terminal:
Minimal reproduction
https://github.com/brandonroberts/angular-i18n-ssr-repro
Exception or error
None. Silent fall-through — no warnings or errors are emitted.
Environment (
ng version)