[Tailwind CSS Angular] Server-side rendering (SSR) with Angular Universal
Server-side rendering (SSR) with Angular Universal
This guide describes Angular Universal, a technology that renders Angular applications on the server.
Why use server-side rendering?
There are three main reasons to create a Universal version of your application.
-
Facilitate web crawlers through search engine optimization (SEO)
-
Improve performance on mobile and low-powered devices
-
Show the first page quickly with a first-contentful paint (FCP)
In this example, the Angular CLI compiles and bundles the Universal version of the application with the Ahead-of-Time (AOT)
compiler. A Node.js Express web server compiles HTML pages with Universal based on client requests.
To create the server-side application module, app.server.module.ts
, run the following CLI command.
1 | ng add @nguniversal/express-engine |
The command creates the following folder structure.
1 | tree . |
The files marked with * are new and not in the original tutorial sample.
Universal in action
To start rendering your application with Universal on your local system, use the following command.
1 | npm run dev:ssr |
Open a browser and navigate to http://localhost:4200/
. You should see the static page.
Navigation using routerLinks
works correctly because they use the native anchor (<a>
) tags.
User events other than routerLink
clicks aren’t supported. You must wait for the full client application to bootstrap and run, or buffer the events using libraries like preboot
angular/preboot: Coordinate transfer of state from server to client view for isomorphic/universal JavaScript web applications - https://github.com/angular/preboot, which allow you to replay these events once the client-side scripts load.
Working around the browser APIs
Because a Universal application doesn’t execute in the browser, some of the browser APIs and capabilities may be missing on the server.
For example, server-side applications can’t reference browser-only global objects such as window
, document
, navigator
, or location
.
Angular provides some injectable abstractions over these objects, such as Location
or DOCUMENT
; it may substitute adequately for these APIs. If Angular doesn’t provide it, it’s possible to write new abstractions that delegate to the browser APIs while in the browser and to an alternative implementation while on the server (aka shimming).
Similarly, without mouse or keyboard events, a server-side application can’t rely on a user clicking a button to show a component. The application must determine what to render based solely on the incoming client request. This is a good argument for making the application routable - https://angular.io/guide/router.
Useful scripts
npm run dev:ssr
This command is similar to ng serve
, which offers live reload during development, but uses server-side rendering. The application will run in watch mode and refresh the browser after every change. This command is slower than the actual ng serve
command.
ng build && ng run app-name:server
This command builds both the server script and the application in production mode. Use this command when you want to build the project for deployment.
npm run serve:ssr
This command starts the server script for serving the application locally with server-side rendering. It uses the build artifacts created by ng run build:ssr
, so make sure you have run that command as well.
Note that serve:ssr
is not intended to be used to serve your application in production, but only for testing the server-side rendered application locally.
**
npm run prerender
This script can be used to prerender an application’s pages. You can read more about prerendering here.
References
[1] Server-side rendering (SSR) with Angular Universal - https://angular.io/guide/universal
[2] Angular - https://angular.io/
Angular - Common Routing Tasks - https://angular.io/guide/router
Angular - Prerendering static pages - https://angular.io/guide/prerendering