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:
windowcan be used to display alerts to the user.
documentbelongs to the
windownamespace and is used to manipulate DOM elements.
navigatorbelongs to the
windownamespace 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:
fsrepresents the file system and is used for CRUD operations.
requestrepresents 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.
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:
Now let's detect user language and implement the
getCurrencyCode() method that returns one of the three available currency codes:
Import the service in src/app/product-details/product-details.component.ts:
Set up a new public field
userCurrency and inject the service in the constructor: