Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore.

15 St Margarets, NY 10033
(+381) 11 123 4567



Server-Side Rendering in Angular | Hacker Noon

Author profile picture


Founder @ dunebook.com and CodeSource.io

The technology that allows us to run our Angular applications on the server is described in the Angular docs as Angular Universal.

Angular Universal generates static application pages on the server through a process called server-side rendering (SSR).

It can generate and serve those pages in response to requests from browsers. It can also pre-generate Angular template as HTML files that you serve later.

A normal  Angular application executes in the browser, rendering pages in the DOM in response to user actions.

In order to improve the user experience, we want to render the pages server side and send the generated static content to the client side, this will ensure that our content is crawlable by search engines and also allow users with  feature phones to consume our content.

In this article you will learn how to add Angular Universal support to any existing Angular app. Let’s get started by installing dependencies

Server Side Rendering¬† ‚Äď Install dependencies

In order to implement server side rendering we need to install some additional dependencies.

Open Terminal enter the following commands:

$ npm install --save @angular/platform-server @nguniversal/module-map-ngfactory-loader ts-loader @nguniversal/express-engine

The root AppModule

Open file 


 and find the


import in the



Replace that import with this one:

BrowserModule.withServerTransition({ appId: 'your App-ID' }),

Create an 


 file in the 


 directory with the following AppServerModule code:

import { NgModule } from '@angular/core';
import { ServerModule } from '@angular/platform-server';
import { ModuleMapLoaderModule } from '@nguniversal/module-map-ngfactory-loader';
import { AppModule } from './app.module';
import { AppComponent } from './app.component';
  imports: [
  providers: [
    // Add universal-only providers here
  bootstrap: [ AppComponent ],
export class AppServerModule {}

Create a 


file in the src directory with the following code:

// These are important and needed before anything else
import 'zone.js/dist/zone-node';
import 'reflect-metadata';

import { enableProdMode } from '@angular/core';

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

// Faster server renders w/ Prod mode (dev mode never needed)

// Express server
const app = express();

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

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

// Express Engine
import { ngExpressEngine } from '@nguniversal/express-engine';
// Import module map for lazy loading
import { provideModuleMap } from '@nguniversal/module-map-ngfactory-loader';

app.engine('html', ngExpressEngine({
  bootstrap: AppServerModuleNgFactory,
  providers: [

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

// TODO: implement data requests securely
app.get('/api/*', (req, res) => {
  res.status(404).send('data requests are not supported');

// Server static files from /browser
app.get('*.*', express.static(join(DIST_FOLDER, 'browser')));

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

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

Tip: This sample server is not secure!

Create a 


 file in the 


 directory to configure TypeScript and AOT compilation of the universal app.

  "extends": "../tsconfig.json",
  "compilerOptions": {
    "outDir": "../out-tsc/app",
    "baseUrl": "./",
    "module": "commonjs",
    "types": []
  "exclude": [
  "angularCompilerOptions": {
    "entryModule": "app/app.server.module#AppServerModule"

Create a 


 file in the project root directory with the following code.

const path = require('path');
const webpack = require('webpack');
module.exports = {
  entry: { server: './server.ts' },
  resolve: { extensions: ['.js', '.ts'] },
  target: 'node',
  // this makes sure we include node_modules and other 3rd party libraries
  externals: [/(node_modules|main..*.js)/],
  output: {
    path: path.join(__dirname, 'dist'),
    filename: '[name].js'
  module: {
    rules: [{ test: /.ts$/, loader: 'ts-loader' }]
  plugins: [
    // Temporary Fix for issue: https://github.com/angular/angular/issues/11580
    // for 'WARNING Critical dependency: the request of a dependency is an expression'
    new webpack.ContextReplacementPlugin(
      path.join(__dirname, 'src'), // location of your src
      {} // a map of your routes
    new webpack.ContextReplacementPlugin(
      path.join(__dirname, 'src'),

Update apps section of

"apps": [{
 "root": "src",
 "outDir": "dist/browser",
 "assets": ["assets", "favicon.ico"],
 "index": "index.html",
 "main": "main.ts",
 "polyfills": "polyfills.ts",
 "test": "test.ts",
 "tsconfig": "tsconfig.app.json",
 "testTsconfig": "tsconfig.spec.json",
 "prefix": "app",
 "styles": ["styles.css"],
 "scripts": [],
 "environmentSource": "environments/environment.ts",
 "environments": {
 "dev": "environments/environment.ts",
 "prod": "environments/environment.prod.ts"
 "platform": "server",
 "root": "src",
 "outDir": "dist/server",
 "assets": ["assets", "favicon.ico"],
 "index": "index.html",
 "main": "main.server.ts",
 "test": "test.ts",
 "tsconfig": "tsconfig.server.json",
 "testTsconfig": "tsconfig.spec.json",
 "prefix": "app",
 "styles": ["styles.css"],
 "scripts": [],
 "environmentSource": "environments/environment.ts",
 "environments": {
 "dev": "environments/environment.ts",
 "prod": "environments/environment.prod.ts"

Build and run with universal

Now that you’ve created the TypeScript and Webpack config files, you can build and run the Angular Universal application.

First add the 


 and serve commands to the scripts section of the 



"scripts": {
    "build:universal": "npm run build:client-and-server-bundles && npm run webpack:server",
    "serve:universal": "node dist/server.js",
    "build:client-and-server-bundles": "ng build --prod && ng build --prod --app 1 --output-hashing=false",
    "webpack:server": "webpack --config webpack.server.config.js --progress --colors",

Build Universal

From Terminal, type:

Serve Universal

After building the application, start the server.

Finally. Open a browser window to 


 and access your Server-side rendered Angular app.


With server-side rendering, we can ensure that search engines, browsers with Javascript disabled, or browsers without Javascript can still access our site content.


  • https://codesource.io/build-a-server-monitoring-app-using-node-angular/

Previously published at https://codesource.io/server-side-rendering-in-angular/


Join Hacker Noon

Create your free account to unlock your custom reading experience.

Credit: Source link

Previous Next
Test Caption
Test Description goes like this