Build Angular 4 Universal apps (Server side rendering) -- Words (1123)

Angular 4 server side rendering

Angular 4 allows developers to build modern SPAs or Single Page Apps which are considered the new apps of the modern web .SPAs have many advantages over old traditional apps such as :

  • The client is responsible of doing the most rendering ,for the server it's major role is serving the app files to the client .
  • Maintaining the state .
  • No page refresh .
  • No server reaching for every action .
  • Easy navigation between different pages .
  • Improved performance .
  • No extra requests to server ,to load new pages .
  • User friendliness etc .

Angular is the most popular and used framework to build Single Page Apps .

So as we have seen ,SPAs have a lot of advantages ,particularly an improved User Experience ,which is what matters the most when building apps .But they have a major SEO problem ,they can't be indexed by Search engines .

Well ,this is not totally correct since Google can index and render JavaScript apps but not all engines are as advanced as Google .Also social networks such as Facebook only understands server rendered html ,you can easily notice this when trying to share an SPA website on Facebook or other social networks .The social network won't be able to recognize the meta content of your shared page such as the title .

So to make sure ,every search engine and social network out there can recognize your website content ,you need to implement the old server side rendering or build what we call Universal apps which are just SPAs with server side rendering.

Getting started with Angular Universal


Angular Universal is a technology that allows server side rendering for Angular apps .

Thanks to Angular universal ,you can build apps that have the best features of both worlds such as

  • Performance Since your app is rendered on the server ,first time users will quickly see a rendered view without waiting for the client to complete rendering .
  • SEO friendliness Many search engines and social networks can read only plain html so to optimize your website for these engines you need to have server side rendering
  • Social networks friendliness By enabling server side rendering ,Social media websites can correclt display previews of your apps or websites when sharing their links .

Starting from Angular 4.0.0 the majority of Angular Universal code is located in @angular/platform-server .

Now lets create an Angular 4 demo project to show how to add server side rendering.

Open your terminal and type

ng new angular-universal-demo
cd angular-universal-demo 

Next install Angular Universal located in @angular/platform-server package

npm install --save @angular/platform-server

You also need to install @angular/animations otherwise you'll get some errors

npm install --save @angular/animations

Open src/app/app.module.ts then update it to reflect these changes :

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http';

import { AppComponent } from './app.component';

@NgModule({
declarations: [
    AppComponent
],
imports: [
    BrowserModule.withServerTransition({appId: 'angular-universal-demo'}),
    FormsModule,
    HttpModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }

Now you need to add a server app module so go ahead and create a new ts file src/app/app.server.module.ts

Then copy and paste the following code

import { NgModule } from '@angular/core';
import { ServerModule } from '@angular/platform-server';
import { AppModule } from './app.module';
import { AppComponent } from './app.component';

@NgModule({
imports: [
    ServerModule,
    AppModule
],
bootstrap: [AppComponent]
})
export class AppServerModule { }

Next create an Express server in src/server.ts

import 'reflect-metadata';
import 'zone.js/dist/zone-node';
import { platformServer, renderModuleFactory } from '@angular/platform-server'
import { enableProdMode } from '@angular/core'
import { AppServerModuleNgFactory } from '../dist/ngfactory/src/app/app.server.module.ngfactory'
import * as express from 'express';
import { readFileSync } from 'fs';
import { join } from 'path';

const PORT = 4000;

enableProdMode();

const app = express();

let template = readFileSync(join(__dirname, '..', 'dist', 'index.html')).toString();

app.engine('html', (_, options, callback) => {
const opts = { document: template, url: options.req.url };

renderModuleFactory(AppServerModuleNgFactory, opts)
    .then(html => callback(null, html));
});

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

app.get('*.*', express.static(join(__dirname, '..', 'dist')));

app.get('*', (req, res) => {
res.render('index', { req });
});

app.listen(PORT, () => {
console.log(`listening on http://localhost:${PORT}!`);
});

Open src/tsconfig.app.json and exclude server.ts

{
"extends": "../tsconfig.json",
"compilerOptions": {
    "outDir": "../out-tsc/app",
    "module": "es2015",
    "baseUrl": "",
    "types": []
},
"exclude": [
    "server.ts",
    "test.ts",
    "**/*.spec.ts"
]
}

Open tsconfig.json and add angularCompilerOptions

{
"compileOnSave": false,
"compilerOptions": {
    "outDir": "./dist/out-tsc",
    "baseUrl": "src",
    "sourceMap": true,
    "declaration": false,
    "moduleResolution": "node",
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "target": "es5",
    "typeRoots": [
    "node_modules/@types"
    ],
    "lib": [
    "es2016",
    "dom"
    ]
},
"angularCompilerOptions": {
    "genDir": "./dist/ngfactory",
    "entryModule": "./src/app/app.module#AppModule"
}  
}

Now you need to install ts-node via npm

npm install -D ts-node

Then open package.json and add these two scripts

"prestart": "ng build --prod && ngc",
"start": "ts-node src/server.ts"

You can now test your demo by running

npm run start

You should be able to visit http://localhost:4000 with your browser to see your old message

app works !

You can find the source code of this demo at GitHub

Conclusion


We have seen how to build Universal SPA apps with Angular 4 which can be rendered on the server side .

This tutorial was inspired from this tutorial at Medium and this GitHub repo


I'm a web developer and technical writer. Passionate about modern JavaScript technologies and currently trying to develop all kind of apps (Web, Mobile and Desktop) with JavaScript.