Server Side Rendering in Angular 7 (Angular Universal)
A normal Angular application executes in the browser and renders pages in the DOM in response to the user’s actions. Angular Universal executes on the server and generates static application pages that later get bootstrapped on the client.
This means that the application generally renders more quickly, giving users a chance to view the application layout before it becomes fully interactive.
Why we should use server-side rendering:
- It facilitates web crawlers through Search Engine Optimization (SEO).
- It improves performance on mobile and low-powered devices.
- It shows the first page quickly.
Steps to create the UNIVERSAL app:
1) To create the server-side app module, app.server.module.ts, run the following CLI command:
ng add @nguniversal/express-engine --clientProject angular.io-example
2) The command creates the following folder structure:
src/ index.html main.ts main.server.ts tsconfig.app.json tsconfig.server.json tsconfig.spec.json style.css app/ … app.server.module.ts server.ts tsconfig.json package.json webpack.server.config.js
3) The ngExpressEngine() function is a wrapper around Universal’s requestModuleFactory() function which turns a client’s requests into server-rendered HTML pages.
In server.ts file, add the code mentioned below:
import 'zone.js/dist/zone-node'; import 'reflect-metadata'; import { enableProdMode } from '@angular/core'; import * as express from 'express'; import { join } from 'path'; import { ngExpressEngine } from '@nguniversal/express-engine'; import { provideModuleMap } from '@nguniversal/module-map-ngfactory-loader'; enableProdMode(); const app = express(); const PORT = process.env.PORT || 5000; const DIST_FOLDER = join(process.cwd(), 'dist'); const { AppServerModuleNgFactory, LAZY_MODULE_MAP } = require('./dist/server/main'); app.engine('html', ngExpressEngine({ bootstrap: AppServerModuleNgFactory, providers: [ provideModuleMap(LAZY_MODULE_MAP) ] })); app.set('view engine', 'html'); app.set('views', join(DIST_FOLDER, 'browser')); app.get('/api/*', (req, res) => { res.status(404).send('data requests are not supported'); }); app.get('*.*', express.static(join(DIST_FOLDER, 'browser'))); app.get('*', (req, res) => { res.render('index', { req }); }); app.listen(PORT, () => { console.log(`Node server listening on http://localhost:${PORT}`); });
4) Add the below-mentioned code to webpack.server.config.js file:
5) Add the below-mentioned code to main.server.ts file:
6) Add the following code in tsconfig.server.json file:
7) Add the below code to file app.server.module.ts:
8) Add server bundle to angular.json file:
"server": { "builder": "@angular-devkit/build-angular:server", "options": { "outputPath": "dist/server", "main": "src/main.server.ts", "tsConfig": "src/tsconfig.server.json" } }
9) Add scripts to package.json file:
"scripts": { "ng": "ng", "start": "ng serve", "test": "ng test", "lint": "tslint ./src/**/*.ts -t verbose", "e2e": "ng e2e", "build:ssr": "npm run build:client-and-server-bundles && npm run webpack:server", "serve:ssr": "node dist/server.js", "build:client-and-server-bundles": "ng build --prod && ng run angular.io example:server", "webpack:server": "webpack --config webpack.server.config.js --progress --colors" }
10) Change BrowserModule import in app.module.ts file:
BrowserModule.withServerTransition({appId: 'angssr'})
11) In app.component.ts write the API you wish to use:
ngOnInit() { this.http.get(‘http://dummy.restapiexample.com/api/v1/employees’).subscribe(data => { console.log(data); }, err =>{ console.log(err); }); }
12) To start rendering your app with Universal on your local system, use the following command:
npm run build:ssr && npm run serve:ssr
13) Open a browser and navigate to http://localhost:4000/ to see the result in the browser.
Found the article interesting? Share it with your friends/co-workers… Now!
If you have any queries or doubts about this topic, please feel free to contact us. We are here to help you!