The technology that allows us to run our Angular applications on the server is described in the Angular docs as Angular Universal. generates application pages on the through a process called . It can generate and serve those pages in response to requests from browsers. It can also pre-generate as HTML files that you serve later. Angular Universal static server server-side rendering (SSR) Angular template A normal Angular application executes in the , rendering pages in the DOM in response to user actions. browser 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/ -map-ngfactory-loader ts-loader @nguniversal/express-engine module The root AppModule Open file and find the import in the metadata. Replace that import with this one: src/app/app.module.ts BrowserModule NgModule BrowserModule.withServerTransition({ : }), appId 'your App-ID' Create an file in the directory with the following AppServerModule code: app.server.module.ts src/app/ { NgModule } ; { ServerModule } ; { ModuleMapLoaderModule } ; { AppModule } ; { AppComponent } ; @NgModule({ : [ AppModule, ServerModule, ModuleMapLoaderModule ], : [ ], : [ AppComponent ], }) {} import from '@angular/core' import from '@angular/platform-server' import from '@nguniversal/module-map-ngfactory-loader' import from './app.module' import from './app.component' imports providers // Add universal-only providers here bootstrap export class AppServerModule Create a file in the src directory with the following code: main.server.ts ; ; { enableProdMode } ; * express ; { join } ; enableProdMode(); app = express(); PORT = process.env.PORT || ; DIST_FOLDER = join(process.cwd(), ); { AppServerModuleNgFactory, LAZY_MODULE_MAP } = ( ); { ngExpressEngine } ; { provideModuleMap } ; app.engine( , ngExpressEngine({ : AppServerModuleNgFactory, : [ provideModuleMap(LAZY_MODULE_MAP) ] })); app.set( , ); app.set( , join(DIST_FOLDER, )); app.get( , (req, res) => { res.status( ).send( ); }); app.get( , express.static(join(DIST_FOLDER, ))); app.get( , (req, res) => { res.render(join(DIST_FOLDER, , ), { req }); }); app.listen(PORT, () => { .log( ); }); // These are important and needed before anything else import 'zone.js/dist/zone-node' import 'reflect-metadata' import from '@angular/core' import as from 'express' import from 'path' // Faster server renders w/ Prod mode (dev mode never needed) // Express server const const 4000 const 'dist' // * NOTE :: leave this as require() since this file is built Dynamically from webpack const require './dist/server/main.bundle' // Express Engine import from '@nguniversal/express-engine' // Import module map for lazy loading import from '@nguniversal/module-map-ngfactory-loader' 'html' bootstrap providers 'view engine' 'html' 'views' 'browser' // implement data requests securely TODO: '/api/*' 404 'data requests are not supported' // Server static files from /browser '*.*' 'browser' // All regular routes use the Universal engine '*' 'browser' 'index.html' // Start up the Node server console `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. tsconfig.server.json /src { : , : { : , : , : , : [] }, : [ , ], : { : } } "extends" "../tsconfig.json" "compilerOptions" "outDir" "../out-tsc/app" "baseUrl" "./" "module" "commonjs" "types" "exclude" "test.ts" "**/*.spec.ts" "angularCompilerOptions" "entryModule" "app/app.server.module#AppServerModule" Create a file in the project root directory with the following code. webpack.server.config.js path = ( ); webpack = ( ); .exports = { : { : }, : { : [ , ] }, : , externals: [ ], : { : path.join(__dirname, ), : }, : { : [{ : , : }] }, : [ webpack.ContextReplacementPlugin( , path.join(__dirname, ), {} ), webpack.ContextReplacementPlugin( , path.join(__dirname, ), {} ) ] }; const require 'path' const require 'webpack' module entry server './server.ts' resolve extensions '.js' '.ts' target 'node' // this makes sure we include node_modules and other 3rd party libraries /(node_modules|main\..*\.js)/ output path '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 /(.+)?angular(\\|\/)core(.+)?/ 'src' // location of your src // a map of your routes new /(.+)?express(\\|\/)(.+)?/ 'src' Update apps section of .angular-cli.json : [{ : , : , : [ , ], : , : , : , : , : , : , : , : [ ], : [], : , : { : , : } }, { : , : , : , : [ , ], : , : , : , : , : , : , : [ ], : [], : , : { : , : } } ], "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 commands to the scripts section of the : build serve package.json : { ... : , : , : , : , ... } "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: npm run build:universal Serve Universal After building the application, start the server. npm run serve:universal Finally. Open a browser window to and access your Server-side rendered Angular app. http://localhost:4000/ Conclusion With server-side rendering, we can ensure that search engines, browsers with disabled, or browsers without Javascript can still access our site content. Javascript References https://codesource.io/build-a-server-monitoring-app-using-node-angular/ Previously published at https://codesource.io/server-side-rendering-in-angular/