Web Development

Setting Up Angular Server-Side Rendering (SSR)

November 6th, 2019 | By Ahmed Bouchefra | 5 min read

In this article, we'll learn about server-side rendering in Angular.

We'll first see why you need to add server-side rendering to your client-side application, and then we'll proceed to add it to an example application.

Let's get started!

Why Do We Need Server-side Rendering?

Angular applications are client-side applications that execute in the browser. Hence, they are rendered on the client, not on the server.

Thanks to Angular Universal, you can add server-side rendering to your app. But why would you need to do that?

There are two reasons to create a server-side version of your application:

  • Performance.
    Rendering Angular on the server side improves the performance of your application, particularly on mobile and low-powered devices, since the browser will not need extra time to render content, which reduces the time for the First-contentful Paint.

  • SEO.
    Server rendering allows search engine crawlers to easily crawl your web app, which helps with Search Engine Optimization. Learn more about SEO basics.

Google can index and render JavaScript apps, but not all engines are as advanced as Google. Also, social networks such as Facebook only understand server-rendered HTML.

You can notice this when sharing your client-side Angular app on social networks.

So, to make sure that every search engine and social network out there can recognize the content of your Angular web app, you need to implement the old server-side rendering or create what we call universal apps, which are client-side JavaScript apps with server-side rendering.

What is Angular Universal?

Angular Universal is a technology that renders Angular applications on the server.

It runs on the server side and generates static pages. These pages are sent to the client browser, allowing the application to render more quickly and giving the user the chance to view the application layout before it becomes fully interactive.


We'll see by example how to enable server-side rendering in Angular applications, so you will need to meet a few prerequisites to follow this tutorial comfortably:

  • You need to have a development environment with Node.js and NPM installed. You can install them from the downloads page of the official website.

    You can also refer to your system documentation for specific instructions on installing Node on your system. A better way is to use NVM, which allows you to install and manage multiple versions.

  • Familiarity with TypeScript.

  • Working knowledge of Angular and familiarity with the basic concepts.

Installing Angular CLI and Creating a New Project

Let's now install Angular CLI and initialize a new project.

Open a new terminal and run the following commands:

npm install -g @angular/cli
ng new angular-universal-example
cd angular-universal-example
ng serve

Your application will be available at http://localhost:4200.

Check out this tutorial for more information.

Setting up Angular Universal in Your Project

After creating your Angular project, let's now see how to add and set up Angular Universal.

You can easily add support for server-side rendering in your app using the Angular CLI thanks to the @nguniversal/express-engine schematic which automatically makes the required steps on behalf of you, as we'll see next.

Head back to a new command-line interface and run the following commands:

cd ~/angular-universal-example
ng add @nguniversal/express-engine --clientProject angular-universal-example

This command will install the required packages and add various files required for setting up SSR:

  • src/main.server.ts,

  • src/app/app.server.module.ts,

  • tsconfig.server.json,

  • webpack.server.config.js,

  • server.ts,

It will also update the following files accordingly:

  • package.json,

  • angular.json,

  • src/main.ts,

  • src/app/app.module.ts

The command will also spin up an Express server for you. Open the server.ts file; you should see the following code:

import 'zone.js/dist/zone-node';

import * as express from 'express';
import {join} from 'path';

// Express server
const app = express();

const PORT = process.env.PORT || 4000;
const DIST_FOLDER = join(process.cwd(), 'dist/browser');

// * NOTE :: leave this as require() since this file is built Dynamically from webpack
const {AppServerModuleNgFactory, LAZY_MODULE_MAP, ngExpressEngine, provideModuleMap} = require('./dist/server/main');

// Our Universal express-engine (found @ https://github.com/angular/universal/tree/master/modules/express-engine)
app.engine('html', ngExpressEngine({
  bootstrap: AppServerModuleNgFactory,
  providers: [

app.set('view engine', 'html');
app.set('views', DIST_FOLDER);

// Example Express Rest API endpoints
// app.get('/api/**', (req, res) => { });
// Serve static files from /browser
app.get('*.*', express.static(DIST_FOLDER, {
  maxAge: '1y'

// All regular routes use the Universal engine
app.get('*', (req, res) => {
  res.render('index', { req });

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

As you can see, in this file, we have a typical Express server with the view engine set to HTML and the views folder set to the dist/browser folder that contains the client-side bundle and which is created when the app is built. The server listens by default on the 4000 port and intercepts possible requests for fetching HTML and static files.

Universal applications make use of the @angular/platform-server
package instead of @angular/platform-browser, which allows you to deliver Angular apps from the server.

On the Express server, requests from the client for fetching application pages are handled by the ngExpressEngine. This simply works by calling the renderModuleFactory() function.

Building and Serving the App with Express Server

Thanks to Angular’s CLI, we've quickly setup Server-side rendering and created a Universal version of our application. The CLI has even created the Express server for us, which takes care of compiling HTML pages with Angular Universal based on client requests.

Now, let's see how to use the Angular CLI to compile and bundle the Universal version of our application and run the Express server to serve the rendered Angular app.

Head back to your terminal, make sure you are inside your Angular project, and run the following commands:

npm run build:ssr 
npm run serve:ssr

This will compile both the Angular app and the server app and launch the Express server from the http://localhost:4000 address. Navigate to this address using your web browser; you should see your Angular app up and running:

You should also see the same application served by the ng serve command from the http://localhost:4200 address, but this is different as it's server-rendered and served by an Express server.


In this article, we've seen that Server-side rendering works by rendering a part of your client-side app on the server instead of the client.

This can help increase performance and allow all search engine crawlers and social media networks to easily crawl your application for SEO purposes.

We also used the Angular CLI and the @nguniversal/express-engine CLI schematic to quickly create a Universal version of our Angular application and prepare our app for server-side rendering.

A final step would be to make sure that our Angular app's source code is protected against code theft, tampering, and reverse engineering.


The leader in client-side Web security. With Jscrambler, JavaScript applications become self-defensive and capable of detecting and blocking client-side attacks like Magecart.

View All Articles

Must read next

Web Development

Setting Up A Parse Server As An Alternative Backend

Parse is a full-fledged mobile backend platform that can be self-hosted. Follow our tutorial to understand how it works and how to set it up.

September 24, 2020 | By Karan Gandhi | 7 min read

Web Development

Building an app with Angular & Firebase

In this tutorial, you will learn how to build a basic CRUD app using Angular and Firebase

August 26, 2021 | By Jay Raj | 11 min read

Section Divider

Subscribe to Our Newsletter