

Internationalization in Angular can follow two different models – build-time or runtime. The official approach uses @angular/localize, which generates a separate build for each language. This setup is stable and fast at runtime, but it requires planning for multiple deployments and no in-app language switching.
To implement it, you mark text in templates and TypeScript, extract translations into files, then build one version of the app per locale. Each language is served from its own URL, so users switch languages through navigation rather than a toggle inside the app.
If you need dynamic switching without reloads, runtime libraries handle that instead. Popular options include ngx-translate and angular-i18next. These load translations on demand and update the UI instantly, with different trade-offs around setup, performance, and SSR support.
In this article, we explain how the built-in Angular internationlization (i18n) workflow works, how to deploy it, and when a runtime library is a better fit.
@angular/localize worksAngular’s built-in internationalization uses a build-time workflow. You prepare translations ahead of deployment, then ship one compiled version of the app per language.
There’s no runtime language switching, so the setup focuses on extraction and build configuration.
Let’s go over the full workflow:
$localize in TypeScript so strings are included in the same extraction process.Pluralization uses ICU expressions. You define cases such as =0, =1, or other, and Angular selects the correct form based on the active locale. Languages differ in how many forms they require, so plan message structure early.
Nested ICU expressions follow the same pattern but increase complexity, so keep them readable and test across locales.
With Angular’s build-time i18n, deployment is tied directly to how you configure angular.json. You define a source locale and a set of target locales, each mapped to a translation file.
During the build, Angular compiles the app once, then applies localized replacements as a post-processing step. This means you are not running full builds per language, but you still end up with separate output bundles for each locale.
Each locale produces its own version of the app, usually served from a subpath or domain. A common setup uses paths like /en/ and /fr/, with each pointing to its corresponding build output. This structure is required because the translated content is baked into the files, so switching languages means loading a different build.
Server configuration becomes part of the i18n setup. You need routing rules that map incoming requests to the correct locale version.
The implementation varies wildly by environment – raw rewrite rules in Nginx versus a few declarative lines in Firebase Hosting – but the goal is the same. Requests must resolve to the right localized bundle based on URL structure or redirect logic.
Angular also supports automatic language detection when using server-side rendering. The server can read the browser’s Accept-Language header, then redirect users to the matching locale path. This improves the first visit experience, but it still results in a full page load when switching languages later.
In development, the Angular dev server can serve multiple locales using subpaths. This helps with testing, but switching between languages still requires a refresh because each locale is a separate build output.
This model has clear infrastructure implications. You manage multiple build artifacts, configure routing for each locale, and handle redirects at the server level. CI pipelines must account for translation updates and rebuild localized outputs when content changes.
An alternative approach avoids this complexity. A reverse proxy model, such as Weglot’s, sits between the server and the browser. It translates content on the fly and serves all languages from a single deployment. This removes the need for multiple builds and routing rules. More on Weglot later on!
Runtime libraries solve a different problem than Angular’s built-in i18n. Instead of compiling translations into the app, they load them at runtime and update the UI without a full reload.
This makes them a better fit when users need to switch languages inside the app or when content changes frequently.
ngx-translate is the most widely used option. It supports instant language switching through translate.use(), with translations loaded from JSON files or APIs. It works well in smaller apps and is the only option here with confirmed Ionic compatibility. SSR is possible with TransferState and custom loaders, though it requires setup. Recent versions added a provider-based API, which aligns better with standalone components.
Transloco focuses on structure and scalability. It provides built-in SSR support and a neater setup with ng add. It also supports scoped translations, which lets you lazy-load language files per feature. This reduces bundle size and keeps large apps maintainable. Language switching uses setActiveLang() and updates the UI immediately.
angular-i18next wraps the i18next ecosystem. It’s useful if your team already uses i18next in other frameworks and wants consistency across projects. It supports plugins from the i18next core, including ICU handling. Language switching typically requires a reload, which limits its use in apps that expect instant updates.
Here’s a more direct comparison:
The choice depends on how your app handles language changes and scale:
💡 If runtime switching isn’t required and you prefer minimal client logic, Angular’s built-in i18n remains the better option.
There’s a third option besides Angular’s built-in i18n and runtime libraries: external website translation tools. These tools sit outside the Angular app and translate the rendered output rather than strings inside the codebase.
As mentioned, Weglot uses a reverse proxy model. It sits between the server and the browser, detects the HTML response, then serves translated versions to visitors. This means you don’t mark strings with i18n, manage JSON translation files, or rebuild the app for each locale. Setup is faster because the translation layer is handled outside Angular.
This approach also changes where translation work happens. Instead of editing files in the project, translators use a visual dashboard. They can review pages and apply glossary rules without touching templates or TypeScript. For content-heavy marketing sites, that can reduce developer involvement.
Language switching can also feel smoother. Weglot supports a JavaScript-based switcher that updates the visible language without requiring a full Angular rebuild process. That makes it easier to launch multilingual content quickly.
The trade-off is control. Because translation happens after Angular renders the page, this model doesn’t handle app logic that depends on language inside TypeScript. It’s also a less-than-ideal fit for Ionic apps and offline-first apps, where content needs to live inside the application itself rather than behind a proxy.
SEO also depends on setup. Reverse proxy translation can support indexable translated pages, but a simple JavaScript snippet alone doesn’t create SEO-friendly localized URLs. That’s important if organic search traffic is part of the goal.
This model is best for teams that want multilingual pages without changing application code. It’s less suitable when language affects routing or business logic. It also requires an active subscription, since translated content remains tied to the service.
The right approach to Angular internationalization depends on how your app handles languages in practice.
Build-time i18n prioritizes performance and stability, while runtime libraries focus on flexibility inside the UI. External tools remove most of the implementation work but shift control outside the codebase.
Choose @angular/localize when runtime performance is vital and your team is comfortable managing separate localized builds in CI. It fits best when language switching can happen through navigation rather than inside the app.
Choose ngx-translate when users need to switch languages without a reload and you want a widely adopted runtime option. It’s the strongest fit here for Ionic projects and smaller Angular apps.
Choose Transloco when you need runtime switching plus stronger structure for larger apps. It’s a good match for SSR setups and for teams that want scoped, lazy-loaded translation files.
Choose Weglot when the goal is a multilingual website without adding translation logic to the Angular codebase. It’s best for content delivery and fast rollout, not for apps where TypeScript behavior needs to change by language.
{{demo-banner}}
The best way to understand the power of Weglot is to see it for yourself. Test it for free and without any engagement.
A demo website is available in your dashboard if you’re not ready to connect your website yet.

No. Each language is compiled into its own build and served from a separate subdirectory. Switching languages means loading a different version of the app, not updating content in place.

Use the $localize tag directly in your code, the same way you mark text in templates. These strings are included during extraction, then replaced with translated content at build time.

The ID changes and existing translations no longer match. This can fail if not configured. Use custom IDs and enable missing translation errors to catch issues early.

Yes. Recent versions added full support through provider-based APIs, so it works with standalone setups.