fix: English UI rendered raw translation keys after the ngx-translate v18 upgrade - #388
Merged
Merged
Conversation
… v18 upgrade Reported after v2.12.0: every label showed its key (NAV.DASHBOARD, AUTH.SIGN_IN), but only in English -- other locales were fine. Cause. The v18 migration (#377) renamed `defaultLanguage` to `fallbackLang` in provideTranslateService(). v17's `defaultLanguage` was inert; v18 loads the fallback language *eagerly from inside the TranslateService constructor*. That resolves TranslateLoader while the injector is still constructing TranslateService, so it fails with: NG0200: Circular dependency detected for `_TranslateService` The loader swallows it as a warning ("error loading translation for en"), so nothing crashed -- English simply never loaded. Every other locale loads later via use(), after bootstrap, when the injector is complete, which is exactly why the failure looked language-specific. Fix. Drop `fallbackLang` from the provider config. I18nService.init() already calls setFallbackLang('en') after bootstrap, which is a safe point. Verified in a real browser, not just unit tests: reproduced on the deployed dev instance (login page rendering AUTH.SITE_TITLE_DEFAULT with the NG0200 warning in console), then built the fix and loaded it locally -- "DM Alerts" / "Sign In" render correctly and the NG0200 warning is gone. The regression tests drive the real appConfig providers rather than a hand-rolled copy. Confirmed they have teeth by re-adding `fallbackLang` and watching them fail with the same NG0200. 875 frontend tests pass, lint and prettier clean.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #389
Fixes the v2.12.0 regression reported in Discord: every UI label renders its raw key (
NAV.DASHBOARD,AUTH.SIGN_IN) — but only in English. Other locales are unaffected.This is my regression from #377, and the "only English" shape is the clue that explains it.
Cause
The v18 migration renamed
defaultLanguage→fallbackLanginprovideTranslateService(). Those are not equivalent in timing:defaultLanguagewas inert — it recorded a preference and loaded nothing.fallbackLangis loaded eagerly, from inside theTranslateServiceconstructor.So the config-level fallback resolves
TranslateLoaderwhile the injector is still constructingTranslateService:The HTTP loader catches this and downgrades it to a console warning (
error loading translation for en), so nothing crashed and CI stayed green — English just never loaded. Every other locale is requested later viause(), after bootstrap, when the injector is complete. Hence a failure that looks language-specific but is really fallback-language-specific.Fix
Drop
fallbackLangfrom the provider config.I18nService.init()already callssetFallbackLang('en')after bootstrap, which is a safe point — no behaviour is lost.Verification
Reproduced in the real deployment first. Loaded the dev instance in a browser and captured both symptom and cause:
Then verified the fix in a browser, built and served locally:
NG0200 gone; the only remaining console errors are failed API calls with no backend running.
Regression tests drive the real
appConfigproviders rather than a hand-rolled copy, so re-addingfallbackLangto the provider config fails CI instead of shipping. Three cases:TranslateServiceconstructs without a circular dependency, no translation is fetched before a language is requested (an eager fallback load would show up here), and English loads through the configured HTTP loader once requested.I confirmed the tests actually catch it by re-introducing
fallbackLangand watching them fail with the sameNG0200: Circular dependency detected for _TranslateService.875 frontend tests pass, lint and prettier clean.
Why unit tests missed it originally
The v18 migration's tests used
provideTranslateService()with no loader, so translations resolved synchronously in-memory and the constructor-time load never happened. The bug needs the real provider wiring — config-levelfallbackLangplus an async HTTP loader — which is exactly what the new tests now supply.