Angular Universal is the process of server-side rendering (SSR) your application to HTML on the Server (ie: Node.js).
Typical Angular applications are Single-Page Applications (aka SPA?s) where the rendering occurs on the Browser. This process can also be referred to as client-side rendering (CSR).
In this article we?ll be taking a deep-dive into understanding: what is Angular Universal, what are the different types of SSR, and how can we setup our applications to become Universal.
1/5/2020 Update: What?s new in Angular Universal v9
New schematic updates, New builders, Live-reload, etc!
Read the full article here
If you?ve been interested in, or looking for information on Angular Universal, you might have 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:
- What is Angular Universal?
- 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.
Check out the Trilon Blog for more articles on Angular, NestJS, and much more!
Part 1 of a deep-dive into 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 !
What is Angular Universal?
Angular Universal is simply the nickname for Server-Side Rendering (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) ?
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 Tutorial
In this tutorial we?re going to look getting started with Angular Universal with help of the Angular CLI.
- First, let?s create a new Angular-CLI Project: Make sure you have the latest Angular-CLI npm i –g @angular/cli
Note: you could skip this and go straight to trying to add Universal to your existing CLI application if you?d like.
ng new some-amazing-project
Now let?s add Angular 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.
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.
2. Next, use ng add to install the Universal schematics to our application.
ng add @nguniversal/express-engine –clientProject [name]// angular.json{ … “projects”: { “some-amazing-project”: {}}
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 Angular Universal for our 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!
Note, you could also shorten these scripts into a script that runs both so it?s even easier for you.
// Dynamic SSRnpm 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
// Static Pre-Renderingnpm 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
Note: 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 it 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>!
Client-side rendered source VS Server-side rendered source.
Angular SEO magic.
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 Universal architecture and deep-dive
- SSR ?Gotchas?
- Tips & Tricks
- Node performance optimization tips
- ASP.NET Core integration & tutorial.
- Much more?
Find me Online !
Twitter: @MarkPieszak Github: @MarkPieszak
Trilon ? Next-level Application Consulting
Trilon.io is a software consulting firm aimed to help get teams & applications up to speed by working with some of the leading industry experts in JavaScript, NodeJS, NestJS Framework & ASP.NET.
Contact us: [email protected]
Website: Trilon.io
Trilon Consulting ? Next-level Application Consulting https://trilon.io
Check out the Trilon Blog for more articles on Angular, NestJS, and much more!