Server-Side Rendering with Angular Universal 🎯

beginner
15 min

Server-Side Rendering with Angular Universal 🎯

Welcome to our deep dive into Angular Universal, a powerful feature that enables Server-Side Rendering (SSR) in Angular applications. Let's embark on a journey to make our Angular apps more efficient, SEO-friendly, and user-friendly!

Understanding Server-Side Rendering 📝

Server-Side Rendering is a technique to render the application on the server rather than the client. It has numerous benefits such as:

  1. Improved SEO: Search engines can easily crawl and index server-rendered pages.
  2. Faster Initial Load: Server-rendered pages provide a faster initial load as JavaScript and other heavy assets are loaded concurrently.
  3. Better Performance on Slow Networks: Server-rendered pages can be fully functional even on slow networks, as much of the content is already loaded on the server.

Angular Universal: A Brief Overview 💡

Angular Universal, a part of the Angular ecosystem, allows us to render Angular applications on the server-side, making it possible to leverage the benefits of Server-Side Rendering.

Setting Up Angular Universal 📝

To get started with Angular Universal, first, we need to install the necessary packages:

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

Next, we need to configure our Angular CLI workspace:

bash
ng generate universal:server

This command will create a server entry point and configure the necessary settings.

Creating a Universal Component 💡

Let's create a simple component that we can render on the server:

bash
ng generate component universal-example

Modify the universal-example.component.ts as follows:

typescript
import { Component, OnInit } from '@angular/core'; import { ServerRenderService } from '../services/server-render.service'; @Component({ selector: 'app-universal-example', templateUrl: './universal-example.component.html', styleUrls: ['./universal-example.component.css'] }) export class UniversalExampleComponent implements OnInit { constructor(private serverRenderService: ServerRenderService) {} ngOnInit() { this.serverRenderService.render(); } }

Here, we've injected the ServerRenderService and called the render() method in the ngOnInit lifecycle hook.

Server-Side Rendering Service 💡

Create a new service named server-render.service.ts:

typescript
import { Injectable } from '@angular/core'; import { ServerResponse } from 'http'; @Injectable({ providedIn: 'root' }) export class ServerRenderService { constructor() {} render() { // Render the component on the server-side this.serverRender(); } private serverRender() { // Implementation of server-side rendering logic // (This example does not cover the actual implementation) } }

We'll implement the serverRender() method shortly.

Configuring the Server 📝

Now, we need to configure our server to use Angular Universal:

  1. Replace the content of main.server.ts with the following:
typescript
import { enableProdMode } from '@angular/core'; import { platformServer } from '@angular/platform-server'; import { AppServerModuleNgFactory, LAZY_MODULE_MAP } from './dist/server/main'; enableProdMode(); export function main(argv: string[]): Promise<void> { return platformServer(AppServerModuleNgFactory, LAZY_MODULE_MAP).bootstrapApplication(argv); }
  1. Update the src/app/app.server.module.ts:
typescript
import { NgModule } from '@angular/core'; import { ServerModule } from '@angular/platform-server'; import { AppServerModule } from './app.server.module'; @NgModule({ imports: [ AppServerModule, ServerModule, ] }) export class AppServerModule { }

Implementing Server-Side Rendering 💡

We'll now implement the serverRender() method in our server-render.service.ts:

typescript
import { Response, Request } from 'express'; import { renderModuleFactory } from '@nguniversal/express-engine'; // ... private async serverRender() { const app = express(); app.engine('.html', ngExpressEngine({ bootstrap: AppModuleNgFactory, providers: [ServerRenderService], })); app.get('*', async (req: Request, res: Response) => { const { AppComponent } = await renderModuleFactory(req, res); // We could further process the AppComponent here res.send(AppComponent.render()); }); app.listen(4000, () => { console.log('Server-side rendering running on port 4000'); }); }

With this implementation, our server will now render Angular components on the server-side and send the HTML to the client.

Testing the Universal Component 💡

To test our Universal component, navigate to http://localhost:4000 in your browser.

Wrapping Up ✅

We've successfully set up and implemented Server-Side Rendering with Angular Universal in our Angular application. This setup can be further extended and optimized to suit real-world projects.

Quiz 🎯

Quick Quiz
Question 1 of 1

What is the main advantage of Server-Side Rendering in Angular applications?