201 Angular App and Nginx - chempkovsky/CS82ANGULAR GitHub Wiki

Notes

  • Current Angular Version = 13
  • Current Nginx Version = 1.22.0
  • We are going to run an angular application under Docker and Nginx is one of the web servers that should be used for this. Let's do short tests to understand the behavior of the localized application and what settings we should apply.
  • First, we will install Nginx in our virtual or network environment.
  • Second, we modify angular.json to unify the settings.
    • there are two different subsection under projects:AngularPhonebook:i18n
      • "sourceLocale": "en-US",
      • "locales": { "ru": { "translation": "src/locale/messages.ru.xlf", "baseHref": "" } }
      • read sourceLocale Reminder
        • we will replace "en-US" with "en"
    • We will add "deployUrl": ... for each locale of the app
  • Third, we modify app.component.html to add a locale switcher.

Steps required to accomplish the task

Install Nginx

  • go to download page and follow the instructions.
    • we installed Nginx for windows.
      • You can use the distribution kit for another operating system.
        • nginx.conf is the only file we will be working with.
      • Of course, some folder paths will be different, but it does not hurt to understand the essence.

Modify angular json

Modify projects:AngularPhonebook:i18n section

  • we added "baseHref":...
  • we replaced en-US with en
    • the new version will be as follows:
Click to show the code
      "i18n": {
        "sourceLocale": {
          "code": "en",
          "baseHref": "en"
        },
        "locales": {
          "ru": {
            "translation": "src/locale/messages.ru.xlf",
            "baseHref": "ru"
          }
        }
      },

Modify projects:AngularPhonebook:architect:build:configurations section

  • the new version will be as follows:
Click to show the code
            "ru": {
              "localize": ["ru"],
            },            
            "en": {
              "localize": ["en"],
            }            

Modify app component html

  • open the app.component.html-file
    • modify <mat-menu #authMainMenu="matMenu"> ... </mat-menu> as follows:
Click to show the code
            <mat-menu #authMainMenu="matMenu">
              <button mat-menu-item [routerLink]="['/authentication/login']">
                <mat-icon>exit_to_app</mat-icon>
                <span>Sign in</span>
              </button>
              <button mat-menu-item  [routerLink]="['/authentication/logout']">
                <mat-icon>link_off</mat-icon>
                <span>Sign out</span>
              </button>
              <button mat-menu-item  [routerLink]="['/authentication/register']">
                <mat-icon>person_add</mat-icon>
                <span>Registration</span>
              </button>
              <button mat-menu-item  [routerLink]="['/authentication/changepassword']">
                <mat-icon>edit</mat-icon>
                <span>Change Password</span>
              </button>
              <a mat-menu-item href="/en/home" >
                  <mat-icon>language</mat-icon>
                  <span>Eng</span>
              </a>
              <a mat-menu-item href="/ru/home" >
                  <mat-icon>language</mat-icon>
                  <span>Ru</span>
              </a>
            </mat-menu>
  • We added two menu items: Eng and Ru

Default build

  • in terminal of the project run the command
ng build
  • This will create the following folders and files
dist
  angular-phonebook
    ru
      ...
    en  
      ...

Copying created folders and files

  • copy angular-phonebook-folder into html-folder of Nginx

Modify nginx conf

  • open nginx.conf-file
    • add the following code in the http { server { ... } }-section
Click to show the code
http {
...
    server {
...
      location /en/ {
        alias html/angular-phonebook/en/;
        try_files $uri$args $uri$args/ /en/index.html;
      }
      location /ru/ {
        alias html/angular-phonebook/ru/;
        try_files $uri$args $uri$args/ /ru/index.html;
      }
      location / {
        alias html/angular-phonebook/ru/;
        try_files $uri$args /ru/index.html;
      }
...
    }
...
}

Restart nginx

  • in the terminal run the command
nginx -s stop
tasklist /fi "imagename eq nginx.exe"
start nginx

First test

  • run the browser
    • go to http://localhost/
  • we redirected to http://localhost/ru/home
    • click Eng-menu item
Click to show the picture

Solution structure

  • we redirected to http://localhost/en/home
    • but the content of the page has not changed (it is still Russian)
    • At the network-panel
      • we can see the request for http://localhost/main.5df2a001e83bb326.js
Click to show the picture

Solution structure

  • To fix the issue we need the request for js-files to be in the form

    • http://localhost/en/XXXX.js
  • Open dist/angular-phonebook/en/index.html

    • instead of src="main.5df2a001e83bb326.js" it must be src="en/main.5df2a001e83bb326.js"
Click to show the code
<!DOCTYPE html><html lang="en" dir="ltr"><head>
  <meta charset="utf-8">
  <title>AngularPhonebook</title>
  <base href="/en">
...
    <script src="runtime.fc7a2a6db549c97a.js" type="module"></script>
    <script src="polyfills.a803562e4f3663dc.js" type="module"></script>
    <script src="main.5df2a001e83bb326.js" type="module"></script>
  </body>
</html>
  • Open dist/angular-phonebook/en/runtime.fc7a2a6db549c97a.js
    • instead of createScriptURL(e),a.p="" it must be createScriptURL(e),a.p="en/"

Modify angular json second time

  • open angular.json-file

Modify projects:AngularPhonebook:architect:build:configurations section

  • "deployUrl": "ru/" and "deployUrl": "en/" added to ru and en subsections:
Click to show the code
            "ru": {
              "localize": ["ru"],
              "deployUrl": "ru/"
            },            
            "en": {
              "localize": ["en"],
              "deployUrl": "en/"
            }            

Build for en

  • in terminal of the project run the command
    • ng build --configuration=en --deploy-url="en/" will work as well
ng build --configuration=en --prod
  • it will create only one folder
dist
  angular-phonebook
    en  
  • copy dist/angular-phonebook/en-folder into html/angular-phonebook/en-folder of Nginx

Build for ru

  • in terminal of the project run the command
    • ng build --configuration=ru --deploy-url="ru/" will work as well
ng build --configuration=ru --prod
  • it will create only one folder
dist
  angular-phonebook
    ru
  • copy dist/angular-phonebook/ru-folder into html/angular-phonebook/ru-folder of Nginx

Second test

  • run the browser
    • go to http://localhost/en/home
  • it works as expected
Click to show the picture

Solution structure

Accept language

  • Let's add automatic language detection
  • open nginx.conf-file and modify as follows:
Click to show the code
http {
...
    # Browser preferred language detection (does NOT require AcceptLanguageModule)
    map $http_accept_language $accept_language {
        ~*^ru ru;
        ~*^en en;
    }
...
    server {
...
      # Fallback to default language if no preference defined by browser
      if ($accept_language ~ "^$") {
          set $accept_language "en";
      }

      location /ru/ {
        alias html/angular-phonebook/ru/;
        try_files $uri$args $uri$args/ /ru/index.html;
      }
      location /en/ {
        alias html/angular-phonebook/en/;
        try_files $uri$args $uri$args/ /en/index.html;
      }
      location / {
        alias html/angular-phonebook/$accept_language/;
        try_files $uri$args $uri$args/ /$accept_language/index.html;
      }
...

Reminder

  • returning to ng serve-commands
ng serve --configuration=ru -o
ng serve --configuration=en -o
  • before running the commands we have to reset back
    • "baseHref":""
    • "deployUrl": ""
⚠️ **GitHub.com Fallback** ⚠️