Adding Internationalization with SSR - The Browser Is Not The Server
Unfortunately, schematics are not a magic wand and they won't solve all of your problems. Sometimes your project needs to be adjusted to do not break Server-Side Rendering process. Here's what might go wrong, and how to address that.
The Browser Is Not The Server#
What can break SSR?#
In the beginning of this module, you've already had a chance to see that some actions can be performed in the browser but not on the server. One such action is performing a REST call using a relative URL. However, this is not the only action that might cause the SSR process to fail.
There are some global objects that are exclusive to the browser:
window
can be used to display alerts to the user.document
belongs to thewindow
namespace and is used to manipulate DOM elements.navigator
belongs to thewindow
namespace and enables service workers that are used extensively with Progressive Web Applications.
There is also a set of objects that are exclusive to the server:
fs
represents the file system and is used for CRUD operations.request
represents the HTTP request retrieved by the server.
Your Angular application has a shared code base for server and browser environments. That's good because you don't need to repeat yourself. However, if you want to use any of these objects, you need to execute a different logic path based on the current runtime: Node.js or the browser window. In this part, you will learn one of the techniques of doing that.
Adding internationalization#
Let's add internationalization to your application. Don't worry, I'm not going to ask you to translate every product description. For now, let's display product prices in three currencies: US dollars, British pounds, and Polish zloty. The application should pick a currency based on browser settings, and if a given language is not supported, it should fall back to Polish zloty.
Let's generate a new service:
ng g s i18n
Now let's detect user language and implement the getCurrencyCode()
method that returns one of the three available currency codes:
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class I18nService {
private userLang;
constructor() {
this.userLang = window.navigator.language;
}
public getCurrencyCode(): string {
switch(this.userLang) {
default:
case 'pl-PL': return 'PLN';
case 'en-US': return 'USD';
case 'en-EN': return 'GBP';
}
}
}
Import the service in src/app/product-details/product-details.component.ts:
import { I18nService } from '../i18n.service';
Set up a new public field userCurrency
and inject the service in the constructor:
public userCurrency: string = this.i18n.getCurrencyCode();
constructor(
private route: ActivatedRoute,
private ps: ProductsService,
private us: UserService,
private i18n: I18nService
) { }
This page is a preview of The newline Guide to Angular Universal