LearnAI ToolsCareerPractice BuildsPlayContact
Lesson 4217 min read

Server-Side Rendering with Angular Universal

Understand why and how to server-render an Angular app for SEO and faster initial paint using Angular Universal.

Why Server-Render an Angular App

A default Angular app renders entirely in the browser — the initial HTML is nearly empty until JavaScript loads and runs. Angular Universal renders that same application to HTML on the server first, giving visitors (and search engine crawlers) meaningful content immediately, before any client-side JavaScript executes.

Built-in, Not a Separate Framework

Unlike React (which needs Next.js) or Vue (which needs Nuxt), Angular Universal is an official Angular capability, addable directly to an existing Angular CLI project rather than requiring a whole separate meta-framework.

Adding SSR to a Project

ng add @angular/ssr

This scaffolds a server entry point and updates your build configuration to produce both a browser bundle and a server-renderable bundle.

npm run build
npm run serve:ssr:my-app

Hydration

Hydration is the process where Angular's client-side code takes over the already-rendered server HTML — attaching event listeners and activating reactivity — without throwing away and re-rendering the DOM from scratch. Modern Angular Universal supports non-destructive hydration by default, meaningfully improving perceived load performance.

// app.config.ts
import { provideClientHydration } from '@angular/platform-browser';
export const appConfig: ApplicationConfig = {
providers: [provideClientHydration()],
};

Writing Server-Safe Code

Code that runs during server rendering has no access to browser-only globals like window, document, or localStorage — referencing them directly during SSR throws an error. Guard such code, or move it into a lifecycle hook that only runs in the browser.

import { Component, inject, PLATFORM_ID } from '@angular/core';
import { isPlatformBrowser } from '@angular/common';
@Component({ selector: 'app-widget', standalone: true, template: `...` })
export class WidgetComponent {
private platformId = inject(PLATFORM_ID);
ngOnInit() {
if (isPlatformBrowser(this.platformId)) {
localStorage.getItem('preference'); // safe — only runs in the browser
}
}
}
Third-Party Libraries Can Break SSR Too

A library that assumes window or document exists at import time (many charting or animation libraries do) can crash server rendering entirely — check for SSR compatibility, or lazy-load such a component only in the browser.

FAQs

No — an app behind a login where SEO doesn't matter (an internal dashboard, for example) is often fine as a client-rendered SPA; SSR is worth the added complexity mainly for public, SEO-sensitive content.

Yes — Angular Universal also supports prerendering specific routes to static HTML at build time, similar in spirit to static site generation in other frameworks.

Summary

Angular Universal brings server-side rendering and hydration directly into the Angular CLI workflow, with careful handling required for browser-only APIs. Next, you'll manage environment-specific configuration for a production Angular app.

Next Lesson →

Environment Configuration