Angular i18n and Server Side Rendering with Angular Universal: Part 2
Tags: angular, npm
Published: 2020-09-04 15:40:20

In the [previous post](https://dev.to/prabhjeet6/angular-i18n-and-server-side-rendering-40bo), we discussed, Angular's *localize package* and how we can run separate locale configurations. 

Here, we will discuss  Angular Universal, a technology that renders Angular applications on the server and how it helps  angular app to be accessible in different sub-directories, depending on the language.

First, we run the below CLI command 
```
ng add @nguniversal/express-engine --clientProject=demoproject
```
Here, clientProject is our existing Angular application.This command generates server-side app module, app.server.module.ts and **Express web server, server.ts** . This web server is used to decide, as to which locale will be rendered for a particular request.   

Next, We modify the Express web server to add the following code. 
```
app.get('*', (req, res) => {
//this is for i18n
  const supportedLocales = ['en', 'pa',...];//supported Locales 
  const defaultLocale = 'en';
  const matches = req.url.match(/^\/([a-z]{2}(?:-[A-Z]{2})?)\//);

  //check if the requested url has a correct format '/locale' and matches any of the supportedLocales
  const locale = (matches && supportedLocales.indexOf(matches[1]) !== -1) ? matches[1] : defaultLocale;

  res.render(`${locale}/index`, { req });
});

// Start up the Node server
app.listen(PORT, () => {
  console.log(`Node Express server listening on http://localhost:${PORT}`);
});

```
 Through this modification, web server identifies the locale of the request, and renders the response accordingly.

You will notice that, in *angular.json*,  **server Configurations** is automatically added once you run `ng add @nguniversal/express-engine` command, which looks like below.
```
"server": {
          "builder": "@angular-devkit/build-angular:server",
          "options": {
            "outputPath": "dist/server",
            "main": "src/main.server.ts",
            "tsConfig": "src/tsconfig.server.json"
          },
          "configurations": {
            "production": {
              "fileReplacements": [
                {
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/environment.prod.ts"
                }
              ]
            },"pa-Guru": {
              "fileReplacements": [
                {
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/environment.prod.ts"
                }
              ]
            },
            "en-US": {
              "fileReplacements": [
                {
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/environment.prod.ts"
                }
              ]
            }
          }
```
In *package.json*, add/modify below scripts according to your project to build and render all locales of your app. 

```
"compile:server": "webpack --config webpack.server.config.js --progress --colors",
    "serve:ssr": "node dist/server",
    "build:ssr": "npm run build:client-and-server-bundles && npm run compile:server",
    "build:client-and-server-bundles": "ng build --configuration=pa-Guru && ng build --configuration=en-US  && ng run demoproject:server:production  &&  ng run demoproject:server:en-US &&  ng run demoproject:server:pa-Guru"

```

Finally, you can run the following command on Angular CLI to render locales through express server and change locales on runtime, depending on the request Url's baseHref.
```
npm run build:ssr && npm run serve:ssr
```

#Benefits of using  Server Side Rendering

Search Engines and  social media sites rely on web crawlers to index your application content and make that content searchable on the web. These web crawlers may be unable to navigate and index your highly interactive Angular application as a human user could do.

Angular Universal can generate a static version of your app that is easily searchable, linkable, and navigable without JavaScript. Universal also makes a site preview available since each URL returns a fully rendered page.

We serve a static version of the landing page to hold the user's attention. At the same time, we'll load the full Angular app behind it. The user perceives near-instant performance from the landing page and gets the full interactive experience after the full app loads.

#Motivation for using Angular i18n over other available libraries

First, we look at some of the **disadvantages**.

* Angular i18n only works with one language at a time, you have to completely reload the application to change the language.
* Angular i18n only supports using i18n in your templates for now.

But, its **Advantages** overpower the drawbacks.

* Angular i18n supports ICU expressions (plurals and select). 
* The translation process is well defined, it is easy to detect 
  missing translations and you can integrate that in your plans 
  before deploying your app (extract, send to translators, merge).
* It scales well, you never look directly at the files since you 
  use a software for that, you can translate in x languages, you 
  just need to extract once and create the translation files for 
  each locale (which your professional tool should do for you)
* It's super efficient because the app is pre-translated when it 
  bootstraps, there's no extra work to apply your translations and * It works well with pre-rendering because of that
  since you merge the translations at build time, it means that it 
  can support directives, components and other html elements, you 
  can move them around in the different languages, or even remove 
  them if needed
* You don't need to worry about lazy loading, your bundles are 
  translated at build time, and that includes your lazy loaded 
  modules.

Thanks for your time. Please share and provide reactions if you like the blog.