Use Server Routes with Angular SSR to granularly specify render modes

2 min read

When building modern Angular applications, especially public-facing ones, Server-Side Rendering (SSR) is a powerful tool for enhancing SEO and improving initial page load performance. But what if you need different rendering strategies for different routes? Angular's Server Routes feature provides an elegant solution for granular control over render modes.

What are Server Routes?

Server Routes allow you to define an array of ServerRoute objects, each specifying a path and a renderMode for that specific route. This means you can mix and match rendering strategies within a single Angular application – choosing between pre-rendering, server-side rendering, or even client-side rendering on a per-route basis.

Why is this useful?

This granular control offers several key benefits:

  • Optimized SEO: Prerender critical, public-facing content (like product pages or blog posts) at build time to ensure search engines can easily index them.
  • Improved Performance: Deliver fully rendered HTML for essential pages, providing a faster initial load experience for users.
  • Flexibility: Use client-side rendering for highly dynamic or user-specific authenticated routes (like a user's wishlist or profile) where SEO isn't a primary concern, or server-side rendering for routes that need fresh data on each request.
  • Dynamic Pre-rendering: Generate static pages for dynamic content (like product categories) by fetching data during the build process, saving on server computation at runtime.

How to use it

Let's look at a practical example where we pre-render product category pages and use client-side rendering for a wishlist.

import { RenderMode, ServerRoute } from '@angular/ssr';
import { CategoriesApi } from './services/categories-api';
import { inject } from '@angular/core';

export const serverRoutes: ServerRoute[] = [
  {
    path: 'products/:categoryName',
    renderMode: RenderMode.Prerender,
    async getPrerenderParams() {
      // Dynamically fetch categories during the build process
      const catService = inject(CategoriesApi);
      const names = await catService.getCategories();
      // Return parameters for each category to be pre-rendered
      return names.map((name) => ({ categoryName: name }));
    },
  },
  {
    path: 'wishlist',
    renderMode: RenderMode.Client, // Client-side rendering for this route
  },
  // ... more routes with different render modes
];

In this snippet:

  1. products/:categoryName: We've set renderMode: RenderMode.Prerender. The getPrerenderParams function is executed at build time. It uses inject to get an instance of CategoriesApi and fetches all category names. For each categoryName, a separate static HTML file will be generated (e.g., /products/electronics, /products/books). Keep in mind that a very large number of categories could significantly increase your build time.
  2. wishlist: This route uses renderMode: RenderMode.Client. This means it will primarily be rendered on the browser, suitable for pages that are highly interactive, user-specific, or don't require immediate SEO benefits. You could also opt for RenderMode.Server here if you wanted server-side rendering without pre-generation.

By exporting this serverRoutes array, your Angular SSR application can intelligently apply the right rendering strategy for each part of your site. It's a simple yet powerful way to build high-performance, SEO-friendly Angular applications.


Full code (with firebase, stripe backend) on my shop: https://zoaibkhan.com/shop/angular-ecommerce?utm_source=server-routes-snippet

You may also like...