[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
2
3
4
5
6
7
8
9
10
11
12
13
$ tree .
src/
index.html app web page
main.ts bootstrapper for client app
main.server.ts * bootstrapper for server app
style.css styles for the app
app/ ... application code
app.server.module.ts * server-side application module
server.ts * express web server
tsconfig.json TypeScript base configuration
tsconfig.app.json TypeScript browser application configuration
tsconfig.server.json TypeScript server application configuration
tsconfig.spec.json TypeScript tests configuration

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/preboot: Coordinate transfer of state from server to client view for isomorphic/universal JavaScript web applications - https://github.com/angular/preboot

Angular - Common Routing Tasks - https://angular.io/guide/router

Angular - Prerendering static pages - https://angular.io/guide/prerendering

Prerender Angular Application using Angular Universal Prerenderer - https://www.ngdevelop.tech/prerender-angular-application-using-angular-universal-prerenderer/