Angular Universal Server-Side Rendering Deep-Dive.

Mark Pieszak | Trilon Consulting
Mark Pieszak

If you’ve been interested in, or looking for information on Angular Universal, you might of had a hard time getting started as there has been many changes over the past few years, and a lot of dated or general misinformation out there!

Let’s change all of that, and get you up to speed, fast!


In this multi-part series, we’re going to look at:

  • Getting setup with Angular Universal
  • The Architecture and behind-the-scenes of SSR.
  • Gotchas, Tips & Tricks of getting even the largest enterprise application running with Angular Universal.

NOTE: Previously Angular Universal was known as angular2-universal on npm, etc. Make sure to ignore any articles or code based on that, since it’s been long deprecated !


Part 1: Server-side Rendering with Angular

Angular Universal is simply the nickname for Server-Side Rendering (or SSR for short) with Angular, technically the package is now found under 🚀 @angular/platform-server. This is in thanks to a lot of great work by PatrickJS, Jeff Whelpley & Angular Core team members Vikram Subramanian & Alex Rickabaugh (many others as well) 👏


So now that we understand a bit of the past & present, let’s dive right into how you can get started server-rendering your Angular applications right now!

Getting started with Angular Universal and the Angular-CLI

I’d highly recommend starting off with the recent integration Universal has with the Angular-CLI.

First, let’s create a new Angular-CLI Project (you could skip this and go straight to trying to add Universal to your existing CLI application if you’d like).

Make sure you have the latest Angular-CLI installed via: npm i --g @angular/cli

Terminal
ng new some-amazing-project

Now let’s add Universal 🍹

As of Angular-CLI version 6.1, there has been an ng add schematic added that allows you to quickly create the scaffolding, Node express server, and other wiring needed to get you started. ✨ Kudos to @Caerusaru for getting this setup!

Angular Universal schematic installation

cd into your root Angular-CLI project directory you’d like to add Universal into, and run the following schematic.

Terminal
ng add @nguniversal/express-engine --clientProject [name]

HINT: Notice the --clientProject [name] portion. Take a look at your angular.json file, and make sure you put the “name” of the project you’re trying to add server-side rendering to.

angular.json
{
...
"projects": {
"some-amazing-project": { } // <-- our clientProject name
}

In the example angular.json above, we’d want to use:

ng add @nguniversal/express-engine --clientProject some-amazing-project

Did we just add all the Universal setup & Node server to our application in 1 line of code?!

Time for a promotion 🏁 🔮


How do we run SSR for our Angular App?

Typically we’d run ng serve to get our normal Client-side rendered (CSR) application fired up…

When we want to build and run our server-side rendered version, we’re going to have to use a few scripts that were added to our package.json.

Before we dive into those important scripts, I want to cover 2 different crucial topics in the server-side rendering world (regardless of JS Framework / etc)…

Dynamic SSR & Static Pre-rendering

Dynamic SSR is the concept that there will be a live Node server spun up that whenever a Route is hit, it will dynamically generate and serialize the application — returning that String to the browser.

Static Pre-rendering is when we want to pre-render a list of routes, and create static files, (ie: index.html, about-us.html, etc) and then use a server of our choosing to serve up those files later on.

So how do we know which one to choose and when?

Pre-rendering will typically give you better performance since we’re not waiting for a server to hit all the necessary APIs within your application, and nothing has to be “serialized”, it already has all the serialized HTML of your application outputted for each one of the Routes files.

Here’s a good list of questions that we consider with clients before considering which route we need to take.

When to use Static Pre-Rendering:

  • Your application itself is rather Static. (or at least the Routes you’re trying to pre-render) For example: homepage | about us | contact us
  • Very dynamic portions of your site (and ones that are behind a Login/Auth barrier) can be pointed to the normal Client-side rendered (CSR) version of your application, and Angular can bootstrap itself normally.
  • Your application doesn’t update very often. Whenever some changes are needed on the static routes, you can simply run the build script again and republish the /dist folder containing all of your pre-rendered files.

When to use Dynamic SSR:

  • Your application (and the routes you need to SSR) are very dynamic 🃏
  • You have a list of “trending products” | “live data” | etc, that you need populated correctly for every server-side render.
  • Your applications structure is rendered based on JSON files or a CMS where anything could change at any given moment.

Typically most applications will need static pre-rendering (since any routes behind an authentication-wall don’t gain much/any benefit from utilizing SSR, since one of the main purposes is the SEO gains, and improved perceived performance.

Remember, you can always have certain aspects of your application not render during SSR, and have those dynamic portions populated during CSR! We’ll get into that in upcoming articles in this series.


How to start up Angular Universal

Going back to our package.json, we can see we have a few new scripts that were added. There were many new scripts added, but if you take a look below — these will give you both methods of SSR right away!

Terminal
// Dynamic SSR
npm run build:ssr && npm run serve:ssr

This will compile your application and spin up a Node Express server to serve your Universal application on http://localhost:4000

Terminal
// Static Pre-Rendering
npm run build:prerender && npm run serve:prerender

This script compiles your application and pre-renders your applications files, spinning up a demo http-server so you can view it on http://localhost:8080

HINT: To deploy your static site to a static hosting platform you will have to deploy the dist/browser folder, rather than the usual dist


So how do we know Universal worked?

Depending on which version (dynamic/static) you fired up, if you access that localhost URL, you should now see that the typical empty <app-root></app-root> will now have content inside it! ✨ ✨

You can set your <title>My Application is amazingggg</title> . You can set your <meta></meta> tags. Your application content will be serialized.

The world is your oyster. 😎

Disable JavaScript or View Source to see the outputted content inside <app-root></app-root>!

With Angular Universal / SSR

<body>
<!-- Look! "app-root" is populated with HTML! -->
<app-root _nghost-sc0="" ng-version="8.0.2">
<div _ngcontent-sc0="" style="text-align:center">
<h1 _ngcontent-sc0="">Welcome to angular-universal-tutorial!</h1>
<!-- ... more html here ... -->
</div></app-root
>
</body>

Regular CSR App

<body>
<!-- Empty! -->
<app-root></app-root>
<!-- ... more html here ... -->
</body>

You did it!

I hope this has helped demystify Angular Universal / Angular SSR for you, if only a little bit. There’s plenty more we’ll be talking about in upcoming articles, so stay tuned!


Manually setting up Angular Universal:

If you’d prefer to add everything yourself, take a look at the CLI Wiki which describes (step-by-step) how to add all the individual pieces to a CLI project: https://github.com/angular/angular-cli/wiki/stories-universal-rendering

Also you can take a peek at the Angular Universal-Starter repo, which is the end-result of the steps shown in the Wiki. All the new files that are needed, setting up the basic Node server, etc.


ASP.NET Core & Angular Universal integration?

Angular Universal has also been integrated with ASP.NET Core (where it itself invokes a small Node process to handle the server-side rendering, piping all of the data back to ASP.NET and rendering it).

ASP.NET Core & Angular Universal repo.

We’ll do a deep-dive into how that is all setup in another article in this series!


See more Universal add-ons & libraries here:
https://github.com/angular/universal

(Angular-CLI Hapi schematics, and more ASP.NET integration tools coming soon…)


Stay tuned for Part 2 & 3 coming soon !

We’re going to take a much deeper look into:

  • Internal Angular SSR architecture and deep-dive
  • SSR “Gotchas”
  • Tips & Tricks
  • Node performance optimization tips
  • ASP.NET Core integration & tutorial.
  • Much more…

Learn NestJS - Official NestJS Courses 📚

Level-up your NestJS and Node.js ecosystem skills in these incremental workshop-style courses, from the NestJS Creator himself, and help support the NestJS framework! 🐈

🚀 The NestJS Fundamentals Course is now LIVE and 25% off for a limited time!

🎉 NEW - NestJS Course Extensions now live!
#Angular
#AngularUniversal
#SSR
#SEO

Share this Post!

📬 Trilon Newsletter

Stay up to date with all the latest Articles & News!

More from the Trilon Blog .

Jay McDoniel | Trilon Consulting
Jay McDoniel

NestJS Metadata Deep Dive

In this article we'll be doing a deep-dive and learning about how NestJS uses Metadata internally for everything from dependency injection, to decorators we use everyday!

Read More
Kamil Mysliwiec | Trilon Consulting
Kamil Mysliwiec

NestJS v10 is now available

Today I am excited to announce the official release of Nest 10: A progressive Node.js framework for building efficient and enterprise-grade, server-side applications.

Read More
Manuel Carballido | Trilon Consulting
Manuel Carballido

Implementing data source agnostic services with NestJS

Learn how to implement data source logic in an agnostic way in yours NestJS applications.

Read More

What we do at Trilon .

At Trilon, our goal is to help elevate teams - giving them the push they need to truly succeed in today's ever-changing tech world.

Trilon - Consulting

Consulting .

Let us help take your Application to the next level - planning the next big steps, reviewing architecture, and brainstorming with the team to ensure you achieve your most ambitious goals!

Trilon - Development and Team Augmentation

Development .

Trilon can become part of your development process, making sure that you're building enterprise-grade, scalable applications with best-practices in mind, all while getting things done better and faster!

Trilon - Workshops on NestJS, Node, and other modern JavaScript topics

Workshops .

Have a Trilon team member come to YOU! Get your team up to speed with guided workshops on a huge variety of topics. Modern NodeJS (or NestJS) development, JavaScript frameworks, Reactive Programming, or anything in between! We've got you covered.

Trilon - Open-source contributors

Open-source .

We love open-source because we love giving back to the community! We help maintain & contribute to some of the largest open-source projects, and hope to always share our knowledge with the world!

Explore more

Write us a message .

Let's talk about how Trilon can help your next project get to the next level.

Rather send us an email? Write to:

hello@trilon.io
© 2019-2023 Trilon.