In-depth Guides
Internationalization

Deploy multiple locales

If myapp is the directory that contains the distributable files of your project, you typically make different versions available for different locales in locale directories. For example, your French version is located in the myapp/fr directory and the Spanish version is located in the myapp/es directory.

The HTML base tag with the href attribute specifies the base URI, or URL, for relative links. If you set the "localize" option in angular.json workspace build configuration file to true or to an array of locale IDs, the CLI adjusts the base href for each version of the application. To adjust the base href for each version of the application, the CLI adds the locale to the configured "subPath". Specify the "subPath" for each locale in your angular.json workspace build configuration file. The following example displays "subPath" set to an empty string.

angular.json

      
{  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",  "version": 1,  "newProjectRoot": "projects",  "projects": {    "angular.io-example": {      "projectType": "application",      "root": "",      "sourceRoot": "src",      "prefix": "app",      "i18n": {        "sourceLocale": "en-US",        "locales": {          "fr": {            "translation": "src/locale/messages.fr.xlf",            "subPath": ""          }        }      },      "architect": {        "build": {          "builder": "@angular-devkit/build-angular:browser",          "options": {            "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": [],            "i18nMissingTranslation": "error"          },          "configurations": {            "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            },            "fr": {              "localize": ["fr"]            }          },          "defaultConfiguration": "production"        },        "serve": {          "builder": "@angular-devkit/build-angular:dev-server",          "configurations": {            "production": {              "buildTarget": "angular.io-example:build:production"            },            "development": {              "buildTarget": "angular.io-example:build:development"            },            "fr": {              "buildTarget": "angular.io-example:build:development,fr"            }          },          "defaultConfiguration": "development"        },        "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": []          }        },        "e2e": {          "builder": "@angular-devkit/build-angular:private-protractor",          "options": {            "protractorConfig": "e2e/protractor.conf.js",            "devServerTarget": "angular.io-example:serve:fr"          },          "configurations": {            "production": {              "devServerTarget": "angular.io-example:serve:production"            }          }        }      }    }  }}

Configure a server

Typical deployment of multiple languages serve each language from a different subdirectory. Users are redirected to the preferred language defined in the browser using the Accept-Language HTTP header. If the user has not defined a preferred language, or if the preferred language is not available, then the server falls back to the default language. To change the language, change your current location to another subdirectory. The change of subdirectory often occurs using a menu implemented in the application.

For more information on how to deploy apps to a remote server, see Deployment.

IMPORTANT: If you are using Hybrid rendering with outputMode set to server, Angular automatically handles redirection dynamically based on the Accept-Language HTTP header. This simplifies deployment by eliminating the need for manual server or configuration adjustments.

Nginx example

The following example displays an Nginx configuration.

      
http {    # Browser preferred language detection (does NOT require    # AcceptLanguageModule)    map $http_accept_language $accept_language {        ~*^de de;        ~*^fr fr;        ~*^en "";    }    # ...}server {    listen 80;    server_name localhost;    root /www/data;    # Fallback to default language if no preference defined by browser    if ($accept_language ~ "^$") {        set $accept_language "fr";    }    # Redirect "/" to Angular application in the preferred language of the browser    rewrite ^/$ /$accept_language permanent;    # Everything under the Angular application is always redirected to Angular in the    # correct language    location ~ ^/(fr|de|$) {        if ($accept_language = "") {            try_files $uri /index.html?$args;        }        try_files $uri /$1/index.html?$args;    }    # ...}

Apache example

The following example displays an Apache configuration.

      
# docregion<VirtualHost *:80>    ServerName localhost    DocumentRoot /www/data    <Directory "/www/data">        # Enable rewrite engine for URL manipulation        RewriteEngine on        RewriteBase /        # Serve 'index.html' for root-level access        RewriteRule ^../index\.html$ - [L]        # If the requested file or directory does not exist, redirect to 'index.html'        RewriteCond %{REQUEST_FILENAME} !-f        RewriteCond %{REQUEST_FILENAME} !-d        RewriteRule (..) $1/index.html [L]        # Language-based redirection based on HTTP Accept-Language header        # Redirect German users to the '/de/' directory        RewriteCond %{HTTP:Accept-Language} ^de [NC]        RewriteRule ^$ /de/ [R]        # Redirect English-speaking users to the '/en/' directory        RewriteCond %{HTTP:Accept-Language} ^en [NC]        RewriteRule ^$ /en/ [R]        # Redirect users with unsupported languages (not 'en' or 'de') to the '/fr/' directory        RewriteCond %{HTTP:Accept-Language} !^en [NC]        RewriteCond %{HTTP:Accept-Language} !^de [NC]        RewriteRule ^$ /fr/ [R]    </Directory></VirtualHost>