September 21, 2023

What is Angular universal: server side rendering

Angular Universal is new technology developed by angular team to render angular on the server-side because if you are executing angular on client-side then there are some SEO issues you need to face because angular executes into the browser dynamically so SEO crawlers are not intelligent enough to execute scripts dynamically. But If you render angular application on the server side then it provides static pages which will help to render application quickly and give advantages to the crawlers.

In this post, we will cover

  1. Setting up Angular server-side rendering
  2. Some practical problems while using angular server-side
  3. Angular universal gotchas
  4. SEO remedies for angular application

Prerequisits: Considering you guys have knowledge in angular, angular-cli

Subscribe to get latest content and also all the content which we don't publish

Setting up angular universal

Before setting up angular universal you should have client-side setup for angular application. For setting up angular client side we will be using angular-cli

ng new angular-universal-demo --routing

the above command will help you to create a client-side project (angular-universal-demo is project name)

After setting up a client project we will add app server module. To create app server module run following command

ng add @nguniversal/express-engine --clientProject angular-universal-demo

Please consider using angular/cli version 8+ else you will end with below issue

angular schematics error

After successfully installing you able to see some new files has been added to your project.Like below

  1. main.server.ts – It will bootstrap server app
  2. app.server.module.ts – It’s server-side application module like app module we have for client-side
  3. server.ts – It’s a web server which will serve our angular universal application
  4. tsconfig.server.json – Typescript configuration on server-side
  5. webpack.server.config.js – Webpack configuration for server-side

In your package.json, there are some scripts added for server-side functionality like

npm run build:ssr

a command like above will be available in your package.json which is used for building the server-side application.

and for running, server-side application command will be

npm run serve:ssr
Angular universal
Angular universal

Above image shows the typical implementation fo angular universal: server-side rendering.

If you are still getting some issue for setting up project so please checkout my git repository.

Considering you are done with the setup of Angular universal.Let’s discuss some practical problems we need to consider while developing server-side application.

Remove XHR round trips

After server-side rendering, angular rerun all the functionality on the client side to create client view, in that all XHR call will be made again which was made on the server. This will make the extra load on your server and crawlers also get confused that webpage still loading.

To avoid this kind of overhead, Angular’s TransferHttpCacheModule will help you. Please check out this link to understand TransferHttpCacheModule and how to use it

Angular universal Gotchas

Until Now , Its look very easy to setup server side rendering but while considering server side rendering you should not deal with DOM directly or some global object like window, location, navigator objects or any library that uses jQuery library. It has some alternative to use it but you want its actual implementation then you need to use it situationally like you need to limiting them in a way that they can be used on client side only

In this case we can use PLATFORM_ID  token to identify whether the current platform is server or browser.

Please check below example.

import { Component, OnInit, Inject, PLATFORM_ID } from '@angular/core';
import { isPlatformBrowser, isPlatformServer } from '@angular/common';
    selector: 'app-platform-id',
    template: ``
export class PlatformIdUseCaseComponent implements OnInit {
    constructor(@Inject(PLATFORM_ID) private platformId) {
    get isBrowser(): boolean {
        return isPlatformBrowser(this.platformId);
    get isServer() {
        return isPlatformServer(this.platformId)
    ngOnInit(): void {
        if (this.isBrowser) {
            console.log('Client only code')
        if (this.isServer) {
            console.log('Server only code');

for more details refer to this link


  • Try not to remove elements from dom which is useful for crawling. Crawlers are sort of dumb if your important part of your content not in page then crawlers will not consider it. Usually, angular developers use *ngIf to hide content that completely removes content from the page. Instead of it simply hide content using CSS or angular hidden property.
  • Don’t user virtual routing like clicking on button or div calling some method inside that you have written navigation logic where we usually use router.navigate(). Actually, as I said crawlers are dumb they will not click on button or div instead of it use an anchor tag with routlink directive because when crawlers see anchor tag and we have linked a page to it then crawlers will take that linked page consideration also.
  • Don’t use virtual scrolling instead of it use pre and next tag because in virtual scrolling content not loaded on the page so crawlers cant capture them but if we have pre and next page type navigation then the page will go through their linked pages. To know Importance of prev and next tags please check this link
  • Don’t underestimate heading tags because when crawlers go through your site it’s easy for crawlers to identify an important part of your content.
  • Add dynamic metadata to your application like below example
import { Component, OnInit } from "@angular/core";
import { Meta, Title } from '@angular/platform-browser';
    selector: 'dynamic-metadat-demo'
export class DynamicMetadatExample implements OnInit {
    constructor(private meta: Meta,
                private title: Title){
    ngOnInit() {
        this.title.setTitle('Page title');
            { name: 'author', content: 'your content' },
            { name: 'keywords', content: 'your tags' },
            { name: 'description', content: 'your summary' }

If you want to know more detail please check this link

  • If you are done with all changes and want to check how your application interacts with crawler please check this site