Angular Universal: What you need to know for SEO
Learn the five steps to make Angular play nicely with search engine bots and index your site.
Keep in mind that “easy” is a relative term here. There’s quite a bit of technical wizardry involved.
You’ll almost certainly need to get a development team involved.
But once the finished product is delivered, your site will serve optimized pages that search engines will easily locate and index.
In this guide, I’ll explain Angular Universal and why it’s important to marketers.
The SEO problem
Angular is a fantastic framework for delivering modular, user-friendly web apps. Unfortunately, it’s a bit hostile to SEO.
That’s for two reasons.
First, Angular relies heavily on script to deliver content. As a result, some search bots don’t “see” the content that a user sees.
Take a look at the Angular Universal documentation. That page is, unsurprisingly, rendered with Angular.
As you scroll down, you’ll see quite a bit of content. You’d think it’s all indexable.
Not necessarily. Right-click on the page and select “View page source” from the context menu that appears.
There are only 100 lines of source code. Nowhere in there will you see the content that you saw when you viewed the page normally.
That, in a nutshell, is the problem with Angular. Human visitors will see the content, but search bots will see the source.
And the source doesn’t have the content!
There’s another SEO problem: speed. Angular apps often don’t load quickly.
Some sites will display a blank screen for a couple of seconds before showing the home page. That can cause visitors to bail as they get impatient.
Site speed is a mobile ranking factor so your rank will take a hit if your site doesn’t load quickly on mobile platforms.
But Google says…
Google claims its bot can index script-driven sites. There’s plenty of evidence to support that, but it doesn’t mean you can avoid going the extra mile when optimizing an Angular site.
For starters, Google isn’t the only search engine in town. If you want your Angular app to rank on Bing and DuckDuckGo, you’ll have to take steps to make that happen.
Next, it may be the case that Google can index some Angular sites, but not yours. Not all Angular apps are created equal. Yours might be the exception to Google’s indexing algorithm.
In my experience, sites that move from HTML to Angular loose massive traffic from search engine a majority of the time. In fact, I’ve had three clients come in over the last year where we had to fix the site back up after the drops due to Angular.
There are solutions
Fortunately, there are ways to make your Angular site SEO friendly.
One of the more popular options is to use dynamic rendering. That’s when you use a tool like Puppeteer to generate static HTML files that web crawlers can more easily consume.
Then, configure your web server to direct search bots to the pre-rendered pages while human visitors navigate around the normal Angular app.
That’s a decent solution, but it still doesn’t address the speed issue. For that, you’ll probably want to go with Angular Universal.
What is Angular Universal?
Angular Universal runs your web app on the server as opposed to running it in the browser.
That’s an important distinction. Normally, Angular apps are client-side applications.
The problem for search bots is that they don’t always “process” client-side code like your browser does when it serves you a web page. That’s why you saw a discrepancy between the Angular Universal documentation page and its source code.
Angular Universal handles server-side rendering (SSR). It pre-renders the HTML and CSS content shown to the user ahead of time.
That means a user will load a static HTML page instead of client-side code. As a result, the page will load more quickly.
Also, because it’s static HTML, search bots can index the content.
Everybody wins.
Why it’s important
If you’re into digital marketing, then you already know that much of the battle involves gaining exposure online. That’s why you reach out to influencers, post updates on social media and optimize your site to rank well.
Simply put: your site can’t rank if it can’t get indexed. If Angular is powering your website, you need to take extra steps to make sure that its content appears in search engines.
That’s why you need an Angular Universal solution.
The downside, of course, is that it’s going to cost money. You’ll need to hire a qualified development team to add SSR to your website.
That’s an expense that should more than pay for itself over time if your site ranks well for key search terms related to your niche.
How to run an Angular App on Angular Universal
If you’re somebody who likes to get your hands dirty with code, or you’d just like to save on development costs, you can deploy a server-side app on your own.
Before you do that, it’s best if you have a basic understanding of Angular, the command-line interface (CLI), TypeScript, and web servers. Otherwise, you’ll likely struggle.
The steps to deploy a Angular Universal app are as follows:
- Install the necessary dependencies
- Update the Angular app
- Use the CLI to build a Universal bundle
- Set up the server to run a Universal bundle
- Run the app on the server
There’s quite a bit going on in those five steps, so I’ll cover them each in turn in the following sections.
Install the dependencies
If you have any experience with Angular, then you already know about Node.js. That’s the runtime that transpiles the TypeScript code into a JavaScript app.
Node.js comes with a package manager, unimaginatively named Node Package Manager or npm for short. You’ll use that to install the dependencies.
Fire up your command line window and run the following code:
npm install –save @angular/platform-server @nguniversal/module-map-ngfactory-loader ts-loader
Give it a few moments (or many moments) to install everything.
Update your Angular App
Next, you’ll need to prepare your Angular app for Universal deployment. That involves four steps:
- Add Universal support. Open your root module (usually AppModule) and add an application ID to the BrowserModule import. You’ll do that in the “imports” section just below the @NgModule declaration.
- Create the server root module.Next, you need to create a new module named AppServerModule. Make sure it imports ServerModule from the platform-server dependency that you added in the previous step.
- Create the main file. You’ll need a main file for your Universal bundle. Create that in the root (in the src folder) and export the AppServerModule class from that file.
- Create a config file. The AppServerModule class needs a config file. Create one in JSON format. It should look something like this:
Create a new build target
Your Angular source directory should include a file named angular.json. You’ll need to update that file in the “architect” section.
It will look something like this:
“architect”: {
“build”: { … }
“server”: {
“builder”: “@angular-devkit/build-angular:server”,
“options”: {
“outputPath”: “dist/my-project-server”,
“main”: “src/main.server.ts”,
“tsConfig”: “src/tsconfig.server.json”
}
}
}
Note the “builder” attribute four lines down. The value after the colon (“server”) is the name of the server. You can update that if you want to name it something else.
Now, you can build your app. Assuming you kept the server named “server,” just head over to your command line and type the following:
ng run my-project:server
You should see output that looks something like this:
Date: 2018-12-12T12:42:09.601Z
Hash: 1caced0e9434007fd7ac
Time: 4122ms
chunk {0} main.js (main) 9.49 kB [entry] [rendered]
chunk {1} styles.css (styles) 0 bytes [entry] [rendered]
Set up the server
Next, you need to set up a Universal server to run the bundle. That’s how you’ll serialize the app and return it to the browser.
To make that happen, create a new file called server.ts. Within that file, you’ll define your app engine.
The details of that code are a little bit outside the scope of this tutorial. Feel free to take a look at the example in the Angular Universal docs.
Run the app on the server
After all of that, you’re finally at a point where you can run the app on the server.
To do that, set up a webpack that handles the server.ts file you created in the previous step.
Name the config file webpack.server.config.js. Once again, check out the Angular Universal docs for the exact kind of code that belongs in the file. You might need to adapt that code to your own naming convention.
Once you’re done with the file, you’ll have two folders under the dist folder: browser and server.
To run the server code, just type the following at the command line:
node dist/server.js
Congratulations! You’re now running server-side code.
Wrapping it up
Although Angular enables developers to rapidly produce high-quality applications, it doesn’t always play nicely with the search engine bots.
Fortunately, Angular Universal can pre-render Angular app pages as static HTML so they’re discoverable and indexable. They’ll also load quicker.
It has always been my recommendation to have an HTML base and use Angular to deliver the other elements on the page. I’ve been making this recommendation about anything JavaScript related since 2010. This process of Angular Universal is the same principal. I can’t tell you have many sites Angular and JavaScript redesigns have destroyed. Be careful with yours and always get it vetting by an SEO company before launch.