Online

Merge translations into the application

To merge the completed translations into your project, complete the following actions

A variant application is a complete copy of the distributable files of your application translated for a single locale.

  1. Use the [Angular CLI][CliMain] to build a copy of the distributable files of your project
  2. Use the "localize" option to replace all of the i18n messages with the valid translations and build a localized variant application.

After you merge the translations, serve each distributable copy of the application using server-side language detection or different subdirectories.

For a compile-time translation of the application, the build process uses ahead-of-time (AOT) compilation to produce a small, fast, ready-to-run application.

The build process works for translation files in the .xlf format or in another format that Angular understands, such as .xtb. For more information about translation file formats used by Angular, see [Change the source language file format][GuideI18nCommonTranslationFilesChangeTheSourceLanguageFileFormat]

To build a separate distributable copy of the application for each locale, [define the locales in the build configuration][GuideI18nCommonMergeDefineLocalesInTheBuildConfiguration] in the [angular.json][GuideWorkspaceConfig] workspace build configuration file of your project.

This method shortens the build process by removing the requirement to perform a full application build for each locale.

To [generate application variants for each locale][GuideI18nCommonMergeGenerateApplicationVariantsForEachLocale], use the "localize" option in the [angular.json][GuideWorkspaceConfig] workspace build configuration file. Also, to [build from the command line][GuideI18nCommonMergeBuildFromTheCommandLine], use the [build][CliBuild] [Angular CLI][CliMain] command with the --localize option.

Define locales in the build configuration

Use the i18n project option in the [angular.json][GuideWorkspaceConfig] workspace build configuration file of your project to define locales for a project.

The following sub-options identify the source language and tell the compiler where to find supported translations for the project.

SuboptionDetails
sourceLocaleThe locale you use within the application source code \(en-US by default\). Can also be an object with code, baseHref, and subPath properties.
localesA map of locale identifiers to translation files. Each entry can also be an object with translation, baseHref, and subPath properties.

For the full list of i18n properties and their types, see [i18n options][GuideWorkspaceConfigI18n].

angular.json for en-US and fr example

For example, the following excerpt of an [angular.json][GuideWorkspaceConfig] workspace build configuration file sets the source locale to en-US and provides the path to the French \(fr\) locale translation file.

angular.json
// #docplaster ...
{
  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
  "version": 1,
  "newProjectRoot": "projects",
  // #docregion locale-config, i18n-subPath
  "projects": {
    "angular.io-example": {
      // #enddocregion locale-config, i18n-subPath
      "projectType": "application",
      "root": "",
      "sourceRoot": "src",
      "prefix": "app",
      // #docregion locale-config, i18n-subPath
      "i18n": {
        "sourceLocale": "en-US",
        "locales": {
          "fr": {
            "translation": "src/locale/messages.fr.xlf",
            // #enddocregion locale-config
            "subPath": ""
            // #docregion locale-config
          }
        }
      },
      // #docregion build-production-french
      "architect": {
        // #enddocregion locale-config, i18n-subPath
        // #docregion build-localize-true, build-single-locale, missing-translation-error
        "build": {
          // #enddocregion build-single-locale
          "builder": "@angular-devkit/build-angular:browser",
          "options": {
            // #enddocregion build-production-french, missing-translation-error
            "localize": true,
            // #enddocregion build-localize-true
            "outputPath": "dist",
            "index": "src/index.html",
            "main": "src/main.ts",
            "polyfills": ["zone.js"],
            "tsConfig": "tsconfig.app.json",
            "assets": ["src/favicon.ico", "src/assets"],
            "styles": ["src/styles.css"],
            "scripts": [],
            // #docregion missing-translation-error
            "i18nMissingTranslation": "error"
            // #docregion build-localize-true, build-production-french
          },
          // #enddocregion build-localize-true, missing-translation-error
          // #docregion build-single-locale
          "configurations": {
            // #enddocregion build-single-locale, build-production-french
            "production": {
              "budgets": [
                {
                  "type": "initial",
                  "maximumWarning": "500kb",
                  "maximumError": "1mb"
                },
                {
                  "type": "anyComponentStyle",
                  "maximumWarning": "2kb",
                  "maximumError": "4kb"
                }
              ],
              "outputHashing": "all"
            },
            "development": {
              "localize": false,
              "buildOptimizer": false,
              "optimization": false,
              "vendorChunk": true,
              "extractLicenses": false,
              "sourceMap": true,
              "namedChunks": true
            },
            // #docregion build-single-locale, build-production-french
            "fr": {
              "localize": ["fr"]
            }
          },
          // #enddocregion build-single-locale, build-production-french
          "defaultConfiguration": "production"
          // #docregion build-single-locale, build-production-french
        },
        "serve": {
          "builder": "@angular-devkit/build-angular:dev-server",
          "configurations": {
            // #enddocregion build-single-locale
            "production": {
              "buildTarget": "angular.io-example:build:production"
            },
            // #enddocregion build-production-french
            "development": {
              "buildTarget": "angular.io-example:build:development"
            },
            // #docregion build-single-locale, build-production-french
            "fr": {
              "buildTarget": "angular.io-example:build:development,fr"
            }
          },
          // #enddocregion build-single-locale, build-production-french
          "defaultConfiguration": "development"
          // #docregion build-single-locale, build-production-french
        },
        // #enddocregion build-single-locale, build-production-french
        "extract-i18n": {
          "builder": "@angular-devkit/build-angular:extract-i18n",
          "options": {
            "buildTarget": "angular.io-example:build"
          }
        },
        "test": {
          "builder": "@angular-devkit/build-angular:karma",
          "options": {
            "polyfills": ["zone.js", "zone.js/testing"],
            "tsConfig": "tsconfig.spec.json",
            "assets": ["src/favicon.ico", "src/assets"],
            "styles": ["src/styles.css"],
            "scripts": []
          }
        }
        // #docregion locale-config, build-single-locale, build-production-french, i18n-subPath
      }
      // #enddocregion build-single-locale, build-production-french
    }
  }
  // #enddocregion i18n-subPath
  // #docregion i18n-subPath
}
// #enddocregion locale-config, i18n-subPath

Generate application variants for each locale

To use your locale definition in the build configuration, use the "localize" option in the [angular.json][GuideWorkspaceConfig] workspace build configuration file to tell the CLI which locales to generate for the build configuration.

  • Set "localize" to true for all the locales previously defined in the build configuration.
  • Set "localize" to an array of a subset of the previously defined locale identifiers to build only those locale versions.
  • Set "localize" to false to disable localization and not generate any locale-specific versions.

If you changed this setting, set "aot" to true in order to use AOT.

If you set the "localize" option to true, define more than one locale, and use ng serve; then an error occurs. If you want to develop against a specific locale, set the "localize" option to a specific locale. For example, for French \(fr\), specify "localize": ["fr"].

The CLI loads and registers the locale data, places each generated version in a locale-specific directory to keep it separate from other locale versions, and puts the directories within the configured outputPath for the project. For each application variant the lang attribute of the html element is set to the locale. The CLI also adjusts the HTML base HREF for each version of the application by adding the locale to the configured baseHref.

Set the "localize" property as a shared configuration to effectively inherit for all the configurations. Also, set the property to override other configurations.

angular.json include all locales from build example

The following example displays the "localize" option set to true in the [angular.json][GuideWorkspaceConfig] workspace build configuration file, so that all locales defined in the build configuration are built.

angular.json
// #docplaster ...
{
  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
  "version": 1,
  "newProjectRoot": "projects",
  // #docregion locale-config, i18n-subPath
  "projects": {
    "angular.io-example": {
      // #enddocregion locale-config, i18n-subPath
      "projectType": "application",
      "root": "",
      "sourceRoot": "src",
      "prefix": "app",
      // #docregion locale-config, i18n-subPath
      "i18n": {
        "sourceLocale": "en-US",
        "locales": {
          "fr": {
            "translation": "src/locale/messages.fr.xlf",
            // #enddocregion locale-config
            "subPath": ""
            // #docregion locale-config
          }
        }
      },
      // #docregion build-production-french
      "architect": {
        // #enddocregion locale-config, i18n-subPath
        // #docregion build-localize-true, build-single-locale, missing-translation-error
        "build": {
          // #enddocregion build-single-locale
          "builder": "@angular-devkit/build-angular:browser",
          "options": {
            // #enddocregion build-production-french, missing-translation-error
            "localize": true,
            // #enddocregion build-localize-true
            "outputPath": "dist",
            "index": "src/index.html",
            "main": "src/main.ts",
            "polyfills": ["zone.js"],
            "tsConfig": "tsconfig.app.json",
            "assets": ["src/favicon.ico", "src/assets"],
            "styles": ["src/styles.css"],
            "scripts": [],
            // #docregion missing-translation-error
            "i18nMissingTranslation": "error"
            // #docregion build-localize-true, build-production-french
          },
          // #enddocregion build-localize-true, missing-translation-error
          // #docregion build-single-locale
          "configurations": {
            // #enddocregion build-single-locale, build-production-french
            "production": {
              "budgets": [
                {
                  "type": "initial",
                  "maximumWarning": "500kb",
                  "maximumError": "1mb"
                },
                {
                  "type": "anyComponentStyle",
                  "maximumWarning": "2kb",
                  "maximumError": "4kb"
                }
              ],
              "outputHashing": "all"
            },
            "development": {
              "localize": false,
              "buildOptimizer": false,
              "optimization": false,
              "vendorChunk": true,
              "extractLicenses": false,
              "sourceMap": true,
              "namedChunks": true
            },
            // #docregion build-single-locale, build-production-french
            "fr": {
              "localize": ["fr"]
            }
          },
          // #enddocregion build-single-locale, build-production-french
          "defaultConfiguration": "production"
          // #docregion build-single-locale, build-production-french
        },
        "serve": {
          "builder": "@angular-devkit/build-angular:dev-server",
          "configurations": {
            // #enddocregion build-single-locale
            "production": {
              "buildTarget": "angular.io-example:build:production"
            },
            // #enddocregion build-production-french
            "development": {
              "buildTarget": "angular.io-example:build:development"
            },
            // #docregion build-single-locale, build-production-french
            "fr": {
              "buildTarget": "angular.io-example:build:development,fr"
            }
          },
          // #enddocregion build-single-locale, build-production-french
          "defaultConfiguration": "development"
          // #docregion build-single-locale, build-production-french
        },
        // #enddocregion build-single-locale, build-production-french
        "extract-i18n": {
          "builder": "@angular-devkit/build-angular:extract-i18n",
          "options": {
            "buildTarget": "angular.io-example:build"
          }
        },
        "test": {
          "builder": "@angular-devkit/build-angular:karma",
          "options": {
            "polyfills": ["zone.js", "zone.js/testing"],
            "tsConfig": "tsconfig.spec.json",
            "assets": ["src/favicon.ico", "src/assets"],
            "styles": ["src/styles.css"],
            "scripts": []
          }
        }
        // #docregion locale-config, build-single-locale, build-production-french, i18n-subPath
      }
      // #enddocregion build-single-locale, build-production-french
    }
  }
  // #enddocregion i18n-subPath
  // #docregion i18n-subPath
}
// #enddocregion locale-config, i18n-subPath

Build from the command line

Also, use the --localize option with the [ng build][CliBuild] command and your existing production configuration. The CLI builds all locales defined in the build configuration. If you set the locales in build configuration, it is similar to when you set the "localize" option to true.

shell
# #docregion add-localize
ng add @angular/localize
# #enddocregion add-localize

# #docregion extract-i18n-default
ng extract-i18n
# #enddocregion extract-i18n-default

# #docregion extract-i18n-output-path
ng extract-i18n --output-path src/locale
# #enddocregion extract-i18n-output-path

# #docregion extract-i18n-formats
ng extract-i18n --format=xlf
ng extract-i18n --format=xlf2
ng extract-i18n --format=xmb
ng extract-i18n --format=json
ng extract-i18n --format=arb
# #enddocregion extract-i18n-formats

# #docregion extract-i18n-out-file
ng extract-i18n --out-file source.xlf
# #enddocregion extract-i18n-out-file

# #docregion build-localize
ng build --localize
# #enddocregion build-localize

# #docregion serve-french
ng serve --configuration=fr
# #enddocregion serve-french

# #docregion build-production-french
ng build --configuration=production,fr
# #enddocregion build-production-french

Apply specific build options for just one locale

To apply specific build options to only one locale, specify a single locale to create a custom locale-specific configuration.

build for French example

The following example displays a custom locale-specific configuration using a single locale.

angular.json
// #docplaster ...
{
  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
  "version": 1,
  "newProjectRoot": "projects",
  // #docregion locale-config, i18n-subPath
  "projects": {
    "angular.io-example": {
      // #enddocregion locale-config, i18n-subPath
      "projectType": "application",
      "root": "",
      "sourceRoot": "src",
      "prefix": "app",
      // #docregion locale-config, i18n-subPath
      "i18n": {
        "sourceLocale": "en-US",
        "locales": {
          "fr": {
            "translation": "src/locale/messages.fr.xlf",
            // #enddocregion locale-config
            "subPath": ""
            // #docregion locale-config
          }
        }
      },
      // #docregion build-production-french
      "architect": {
        // #enddocregion locale-config, i18n-subPath
        // #docregion build-localize-true, build-single-locale, missing-translation-error
        "build": {
          // #enddocregion build-single-locale
          "builder": "@angular-devkit/build-angular:browser",
          "options": {
            // #enddocregion build-production-french, missing-translation-error
            "localize": true,
            // #enddocregion build-localize-true
            "outputPath": "dist",
            "index": "src/index.html",
            "main": "src/main.ts",
            "polyfills": ["zone.js"],
            "tsConfig": "tsconfig.app.json",
            "assets": ["src/favicon.ico", "src/assets"],
            "styles": ["src/styles.css"],
            "scripts": [],
            // #docregion missing-translation-error
            "i18nMissingTranslation": "error"
            // #docregion build-localize-true, build-production-french
          },
          // #enddocregion build-localize-true, missing-translation-error
          // #docregion build-single-locale
          "configurations": {
            // #enddocregion build-single-locale, build-production-french
            "production": {
              "budgets": [
                {
                  "type": "initial",
                  "maximumWarning": "500kb",
                  "maximumError": "1mb"
                },
                {
                  "type": "anyComponentStyle",
                  "maximumWarning": "2kb",
                  "maximumError": "4kb"
                }
              ],
              "outputHashing": "all"
            },
            "development": {
              "localize": false,
              "buildOptimizer": false,
              "optimization": false,
              "vendorChunk": true,
              "extractLicenses": false,
              "sourceMap": true,
              "namedChunks": true
            },
            // #docregion build-single-locale, build-production-french
            "fr": {
              "localize": ["fr"]
            }
          },
          // #enddocregion build-single-locale, build-production-french
          "defaultConfiguration": "production"
          // #docregion build-single-locale, build-production-french
        },
        "serve": {
          "builder": "@angular-devkit/build-angular:dev-server",
          "configurations": {
            // #enddocregion build-single-locale
            "production": {
              "buildTarget": "angular.io-example:build:production"
            },
            // #enddocregion build-production-french
            "development": {
              "buildTarget": "angular.io-example:build:development"
            },
            // #docregion build-single-locale, build-production-french
            "fr": {
              "buildTarget": "angular.io-example:build:development,fr"
            }
          },
          // #enddocregion build-single-locale, build-production-french
          "defaultConfiguration": "development"
          // #docregion build-single-locale, build-production-french
        },
        // #enddocregion build-single-locale, build-production-french
        "extract-i18n": {
          "builder": "@angular-devkit/build-angular:extract-i18n",
          "options": {
            "buildTarget": "angular.io-example:build"
          }
        },
        "test": {
          "builder": "@angular-devkit/build-angular:karma",
          "options": {
            "polyfills": ["zone.js", "zone.js/testing"],
            "tsConfig": "tsconfig.spec.json",
            "assets": ["src/favicon.ico", "src/assets"],
            "styles": ["src/styles.css"],
            "scripts": []
          }
        }
        // #docregion locale-config, build-single-locale, build-production-french, i18n-subPath
      }
      // #enddocregion build-single-locale, build-production-french
    }
  }
  // #enddocregion i18n-subPath
  // #docregion i18n-subPath
}
// #enddocregion locale-config, i18n-subPath

Pass this configuration to the ng serve or ng build commands. The following code example displays how to serve the French language file.

shell
# #docregion add-localize
ng add @angular/localize
# #enddocregion add-localize

# #docregion extract-i18n-default
ng extract-i18n
# #enddocregion extract-i18n-default

# #docregion extract-i18n-output-path
ng extract-i18n --output-path src/locale
# #enddocregion extract-i18n-output-path

# #docregion extract-i18n-formats
ng extract-i18n --format=xlf
ng extract-i18n --format=xlf2
ng extract-i18n --format=xmb
ng extract-i18n --format=json
ng extract-i18n --format=arb
# #enddocregion extract-i18n-formats

# #docregion extract-i18n-out-file
ng extract-i18n --out-file source.xlf
# #enddocregion extract-i18n-out-file

# #docregion build-localize
ng build --localize
# #enddocregion build-localize

# #docregion serve-french
ng serve --configuration=fr
# #enddocregion serve-french

# #docregion build-production-french
ng build --configuration=production,fr
# #enddocregion build-production-french

For production builds, use configuration composition to run both configurations.

shell
# #docregion add-localize
ng add @angular/localize
# #enddocregion add-localize

# #docregion extract-i18n-default
ng extract-i18n
# #enddocregion extract-i18n-default

# #docregion extract-i18n-output-path
ng extract-i18n --output-path src/locale
# #enddocregion extract-i18n-output-path

# #docregion extract-i18n-formats
ng extract-i18n --format=xlf
ng extract-i18n --format=xlf2
ng extract-i18n --format=xmb
ng extract-i18n --format=json
ng extract-i18n --format=arb
# #enddocregion extract-i18n-formats

# #docregion extract-i18n-out-file
ng extract-i18n --out-file source.xlf
# #enddocregion extract-i18n-out-file

# #docregion build-localize
ng build --localize
# #enddocregion build-localize

# #docregion serve-french
ng serve --configuration=fr
# #enddocregion serve-french

# #docregion build-production-french
ng build --configuration=production,fr
# #enddocregion build-production-french
angular.json
// #docplaster ...
{
  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
  "version": 1,
  "newProjectRoot": "projects",
  // #docregion locale-config, i18n-subPath
  "projects": {
    "angular.io-example": {
      // #enddocregion locale-config, i18n-subPath
      "projectType": "application",
      "root": "",
      "sourceRoot": "src",
      "prefix": "app",
      // #docregion locale-config, i18n-subPath
      "i18n": {
        "sourceLocale": "en-US",
        "locales": {
          "fr": {
            "translation": "src/locale/messages.fr.xlf",
            // #enddocregion locale-config
            "subPath": ""
            // #docregion locale-config
          }
        }
      },
      // #docregion build-production-french
      "architect": {
        // #enddocregion locale-config, i18n-subPath
        // #docregion build-localize-true, build-single-locale, missing-translation-error
        "build": {
          // #enddocregion build-single-locale
          "builder": "@angular-devkit/build-angular:browser",
          "options": {
            // #enddocregion build-production-french, missing-translation-error
            "localize": true,
            // #enddocregion build-localize-true
            "outputPath": "dist",
            "index": "src/index.html",
            "main": "src/main.ts",
            "polyfills": ["zone.js"],
            "tsConfig": "tsconfig.app.json",
            "assets": ["src/favicon.ico", "src/assets"],
            "styles": ["src/styles.css"],
            "scripts": [],
            // #docregion missing-translation-error
            "i18nMissingTranslation": "error"
            // #docregion build-localize-true, build-production-french
          },
          // #enddocregion build-localize-true, missing-translation-error
          // #docregion build-single-locale
          "configurations": {
            // #enddocregion build-single-locale, build-production-french
            "production": {
              "budgets": [
                {
                  "type": "initial",
                  "maximumWarning": "500kb",
                  "maximumError": "1mb"
                },
                {
                  "type": "anyComponentStyle",
                  "maximumWarning": "2kb",
                  "maximumError": "4kb"
                }
              ],
              "outputHashing": "all"
            },
            "development": {
              "localize": false,
              "buildOptimizer": false,
              "optimization": false,
              "vendorChunk": true,
              "extractLicenses": false,
              "sourceMap": true,
              "namedChunks": true
            },
            // #docregion build-single-locale, build-production-french
            "fr": {
              "localize": ["fr"]
            }
          },
          // #enddocregion build-single-locale, build-production-french
          "defaultConfiguration": "production"
          // #docregion build-single-locale, build-production-french
        },
        "serve": {
          "builder": "@angular-devkit/build-angular:dev-server",
          "configurations": {
            // #enddocregion build-single-locale
            "production": {
              "buildTarget": "angular.io-example:build:production"
            },
            // #enddocregion build-production-french
            "development": {
              "buildTarget": "angular.io-example:build:development"
            },
            // #docregion build-single-locale, build-production-french
            "fr": {
              "buildTarget": "angular.io-example:build:development,fr"
            }
          },
          // #enddocregion build-single-locale, build-production-french
          "defaultConfiguration": "development"
          // #docregion build-single-locale, build-production-french
        },
        // #enddocregion build-single-locale, build-production-french
        "extract-i18n": {
          "builder": "@angular-devkit/build-angular:extract-i18n",
          "options": {
            "buildTarget": "angular.io-example:build"
          }
        },
        "test": {
          "builder": "@angular-devkit/build-angular:karma",
          "options": {
            "polyfills": ["zone.js", "zone.js/testing"],
            "tsConfig": "tsconfig.spec.json",
            "assets": ["src/favicon.ico", "src/assets"],
            "styles": ["src/styles.css"],
            "scripts": []
          }
        }
        // #docregion locale-config, build-single-locale, build-production-french, i18n-subPath
      }
      // #enddocregion build-single-locale, build-production-french
    }
  }
  // #enddocregion i18n-subPath
  // #docregion i18n-subPath
}
// #enddocregion locale-config, i18n-subPath

Report missing translations

When a translation is missing, the build succeeds but generates a warning such as Missing translation for message "{translation_text}". To configure the level of warning that is generated by the Angular compiler, specify one of the following levels.

Warning levelDetailsOutput
errorThrow an error and the build failsn/a
ignoreDo nothingn/a
warningDisplays the default warning in the console or shellMissing translation for message "{translation_text}"

Specify the warning level in the options section for the build target of your [angular.json][GuideWorkspaceConfig] workspace build configuration file.

angular.json error warning example

The following example displays how to set the warning level to error.

angular.json
// #docplaster ...
{
  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
  "version": 1,
  "newProjectRoot": "projects",
  // #docregion locale-config, i18n-subPath
  "projects": {
    "angular.io-example": {
      // #enddocregion locale-config, i18n-subPath
      "projectType": "application",
      "root": "",
      "sourceRoot": "src",
      "prefix": "app",
      // #docregion locale-config, i18n-subPath
      "i18n": {
        "sourceLocale": "en-US",
        "locales": {
          "fr": {
            "translation": "src/locale/messages.fr.xlf",
            // #enddocregion locale-config
            "subPath": ""
            // #docregion locale-config
          }
        }
      },
      // #docregion build-production-french
      "architect": {
        // #enddocregion locale-config, i18n-subPath
        // #docregion build-localize-true, build-single-locale, missing-translation-error
        "build": {
          // #enddocregion build-single-locale
          "builder": "@angular-devkit/build-angular:browser",
          "options": {
            // #enddocregion build-production-french, missing-translation-error
            "localize": true,
            // #enddocregion build-localize-true
            "outputPath": "dist",
            "index": "src/index.html",
            "main": "src/main.ts",
            "polyfills": ["zone.js"],
            "tsConfig": "tsconfig.app.json",
            "assets": ["src/favicon.ico", "src/assets"],
            "styles": ["src/styles.css"],
            "scripts": [],
            // #docregion missing-translation-error
            "i18nMissingTranslation": "error"
            // #docregion build-localize-true, build-production-french
          },
          // #enddocregion build-localize-true, missing-translation-error
          // #docregion build-single-locale
          "configurations": {
            // #enddocregion build-single-locale, build-production-french
            "production": {
              "budgets": [
                {
                  "type": "initial",
                  "maximumWarning": "500kb",
                  "maximumError": "1mb"
                },
                {
                  "type": "anyComponentStyle",
                  "maximumWarning": "2kb",
                  "maximumError": "4kb"
                }
              ],
              "outputHashing": "all"
            },
            "development": {
              "localize": false,
              "buildOptimizer": false,
              "optimization": false,
              "vendorChunk": true,
              "extractLicenses": false,
              "sourceMap": true,
              "namedChunks": true
            },
            // #docregion build-single-locale, build-production-french
            "fr": {
              "localize": ["fr"]
            }
          },
          // #enddocregion build-single-locale, build-production-french
          "defaultConfiguration": "production"
          // #docregion build-single-locale, build-production-french
        },
        "serve": {
          "builder": "@angular-devkit/build-angular:dev-server",
          "configurations": {
            // #enddocregion build-single-locale
            "production": {
              "buildTarget": "angular.io-example:build:production"
            },
            // #enddocregion build-production-french
            "development": {
              "buildTarget": "angular.io-example:build:development"
            },
            // #docregion build-single-locale, build-production-french
            "fr": {
              "buildTarget": "angular.io-example:build:development,fr"
            }
          },
          // #enddocregion build-single-locale, build-production-french
          "defaultConfiguration": "development"
          // #docregion build-single-locale, build-production-french
        },
        // #enddocregion build-single-locale, build-production-french
        "extract-i18n": {
          "builder": "@angular-devkit/build-angular:extract-i18n",
          "options": {
            "buildTarget": "angular.io-example:build"
          }
        },
        "test": {
          "builder": "@angular-devkit/build-angular:karma",
          "options": {
            "polyfills": ["zone.js", "zone.js/testing"],
            "tsConfig": "tsconfig.spec.json",
            "assets": ["src/favicon.ico", "src/assets"],
            "styles": ["src/styles.css"],
            "scripts": []
          }
        }
        // #docregion locale-config, build-single-locale, build-production-french, i18n-subPath
      }
      // #enddocregion build-single-locale, build-production-french
    }
  }
  // #enddocregion i18n-subPath
  // #docregion i18n-subPath
}
// #enddocregion locale-config, i18n-subPath

This means that your Angular application is translated after compilation. This also means that you can create localized versions of your Angular application without re-compiling your entire Angular project for each locale.

When you translate your Angular application, the translation transformation replaces and reorders the parts \(static strings and expressions\) of the template literal string with strings from a collection of translations. For more information, see [$localize][ApiLocalizeInitLocalize].

TLDR: Compile once, then translate for each locale.

What's next

[ApiLocalizeInitLocalize]: api/localize/init/$localize '$localize | init - localize - API | Angular' [CliMain]: cli 'CLI Overview and Command Reference | Angular' [CliBuild]: cli/build 'ng build | CLI | Angular' [GuideBuild]: tools/cli/build 'Building and serving Angular apps | Angular' [GuideI18nCommonMergeApplySpecificBuildOptionsForJustOneLocale]: guide/i18n/merge#apply-specific-build-options-for-just-one-locale 'Apply specific build options for just one locale - Merge translations into the application | Angular' [GuideI18nCommonMergeBuildFromTheCommandLine]: guide/i18n/merge#build-from-the-command-line 'Build from the command line - Merge translations into the application | Angular' [GuideI18nCommonMergeDefineLocalesInTheBuildConfiguration]: guide/i18n/merge#define-locales-in-the-build-configuration 'Define locales in the build configuration - Merge translations into the application | Angular' [GuideI18nCommonMergeGenerateApplicationVariantsForEachLocale]: guide/i18n/merge#generate-application-variants-for-each-locale 'Generate application variants for each locale - Merge translations into the application | Angular' [GuideI18nCommonTranslationFilesChangeTheSourceLanguageFileFormat]: guide/i18n/translation-files#change-the-source-language-file-format 'Change the source language file format - Work with translation files | Angular' [GuideWorkspaceConfig]: reference/configs/workspace-config 'Angular workspace configuration | Angular' [GuideWorkspaceConfigI18n]: reference/configs/workspace-config#i18n-options 'i18n options - Angular workspace configuration | Angular'