Skip to content

Instantly share code, notes, and snippets.

@drewwiens
Last active April 14, 2022 20:14
Show Gist options
  • Save drewwiens/51e1c9f126be27e7a49f368b48ee9008 to your computer and use it in GitHub Desktop.
Save drewwiens/51e1c9f126be27e7a49f368b48ee9008 to your computer and use it in GitHub Desktop.
(i18n) A simple way to dynamically load Angular translations

Problem

Calling loadTranslations() in either main.ts or in a resolved Promise does not work, at least in Angular 9 rc12. The function has to be called synchronously in polyfills.ts, so the translations also have to be available as a JS object, i.e. you can't fetch or XHR the JSON.

Solution

You could require() the JSON file in polyfills.ts, but then the JSON for all the languages will be in the bundle. (Try it and search for each JSON in polyfills.js.)

Alternatively, save each translation as a .js file and add a <script> tag to load only the desired translations.

Example

index.html

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>I18nNg9rc12</title>
  <base href="/">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/x-icon" href="favicon.ico">
  <script src="/assets/i18n/preload.js"></script>
</head>
<body>
  <app-root></app-root>
</body>
</html>

preload.js

const script = document.createElement('script');
const userLang = localStorage.getItem('lang');
const autoLang = window.navigator.language.slice(0, 2);
script.src = `/assets/i18n/${userLang || autoLang}.js`;
script.async = false;
script.defer = false;
document.head.appendChild(script);

en.js

const translations = {
  "someId": "Some Translation"
}

polyfills.ts

import '@angular/localize/init';
import { loadTranslations } from '@angular/localize';

declare const translations: Record<string, string>; // From preload.js

loadTranslations(translations);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment