Today, I will show you how to optimize your Angular 5 and above for search engine and other crawlers. It is important to note that, pages behind a sign in page don’t need to be optimized and you should only concentrate on publicly accessible pages. We are going to take a few steps to prepare our app for search engine optimization like adding page title and meta tags to your pages.

Adding Meta Tags and Page Title

The important part of Search Engine Optimization is to add a page title and some Metatags i.e. description, keywords, twitter cards and Facebook Graph tags if you wish. You need to add this to the different pages of your Angular app dynamically. To achieve this, you will embed them on to your routes inside your router. Add a new route property called data and then add some objects like page title and metatags to it as shown below.

[
  // ... other routes
  {
    component: AngularComponent,
    path: '',
    data: {
      title: 'Page Title',
      metatags: {
        description: 'Page Description or some content here',
        keywords: 'some, keywords, here, separated, by, a comma'
      }
    }
  }
  // ... other routes
];

Note: I have grouped all my metatags under one key, instead of spreading them at the root of data property. This will allow me to add them to the pages meta using a for-loop instead of adding each manually. This allows me to have varying number of metatags in different pages and the loop will add all of them.

SEO Service

Create a new service using Angular CLI called SEOServices as shown below ng g service SEO Open the service and import the Title and Meta service from @angular/platform-browser and Router and NavigationEnd from @angular/router modules.

import { Title, Meta } from '@angular/platform-browser';
import { Router, NavigationEnd } from '@angular/router';

Next, initialize the services inside the constructor:

public constructor(
    private titleService: Title,
    private metaService: Meta,
    private router: Router,
) {}

Next, create a method to add metatags and the page title to the page as show below:

public addSeoData() : void {
  this.router.events.filter((event: any) => event instanceof NavigationEnd).subscribe(() => {
      var root = this.router.routerState.snapshot.root;
      while (root) {
        if (root.children && root.children.length) {
          root = root.children[0];
        } else if (root.data && root.data["title"]) {
          this.titleService.setTitle(root.data["title"] + " | App Name");
          let tags = root.data["metatags"];
          for (let tag in tags) {
            this.metaService.addTag({ name: tag, content: tags[tag] });
          }
          return;
        } else {
         return;
        }
      }
    });
}

The above function loops through your hierarchy of roots until it finds the lowest root with a page title and meta tags, then adds the particulars to the page header. So, you can have a page title and meta tags to a parent root that all its children will inherit. Finally, call the service from the root component of your application (somewhere else is fine too).

public constructor (private seoService: SEOService)
{
      seoService. addSeoData()
}

Note: Remember to follow all the search engine optimization best practices for both metatags and the content. This just gives a way of achieving that but it’s not a comprehensive guide for Search Engine Optimization.

Prerendering of Content

We have now taken care of Metadata and Page Titles, now let’s take care of the big issue. Single page applications are rendered on the browser but Angular Introduced Angular Server-Side Rendering or Angular Universal to render them on the server just like PHP or any server-side scripts. At the moment, only 2 backends support Angular Universal – NodeJS and ASP.NET. Support for PHP, Java and Python will come at a latter unspecified date.

Instead of using Angular Universal, we are going to use a prerender.io service that supports almost all backends out there. This will prerender and cache your live Angular Application and serve it to bots and crawlers. This allows you app to play nice with your users and at the same time with Search Engines.

On top of that, if your app is small – less than 250 pages – you get to pay nothing and even if your app is large, their prices are quite reasonable. To get started, head over to their site and create an account, use this link to signup.

Make sure you confirm your email address and add some billing info just incase you go over their free limit. Then add your site, by clicking add url button and wait for their service to crawl and generate prerendered version of your site.

You can view the prerendered version of your app by clicking view raw html button next to your site, in the preview column. The only thing that’s remaining is integrating it with your server or backend so that it serves the prerendered version to bots and crawlers.

If you head over here, you will notice it is has support for a very huge number of backends and servers. Scroll through the list and find the backend you are using to get instruction on how to integrate it with Prerender.

Apache Server

I will show you how to add it to your apache server. Assuming you already are using Apache serve to server your Angular app, then you must have a .htaccess file to redirect all paths to index.html to avoid an error 404. Your htaccess resembles something like this:

RewriteEngine on
RewriteRule ^ index.html [QSA,L]

Add the following to your .htaccess access file:

#RequestHeader set X-Prerender-Token "YOUR_TOKEN"

<IfModule mod_proxy_http.c>
        RewriteCond %{HTTP_USER_AGENT} baiduspider|facebookexternalhit|twitterbot|rogerbot|linkedinbot|embedly|quora link preview|showyoubot|outbrain|pinterest|slackbot|vkShare|W3C_Validator [NC,OR]
        RewriteCond %{QUERY_STRING} _escaped_fragment_   
       # Only proxy the request to Prerender if it's a request for HTML
        RewriteRule ^(?!._?(.js|.css|.xml|.less|.png|.jpg|.jpeg|.gif|.pdf|.doc|.txt|.ico|.rss|.zip|.mp3|.rar|.exe|.wmv|.doc|.avi|.ppt|.mpg|.mpeg|.tif|.wav|.mov|.psd|.ai|.xls|.mp4|.m4a|.swf|.dat|.dmg|.iso|.flv|.m4v|.torrent|.ttf|.woff))(._) http://service.prerender.io/http://example.com/$2 [P,L]
</IfModule>

Note: You can get the token from your account page next to the header. You can get the full .htaccess file here. And voila, you have an angular application that has been optimized for search engines and bots without doing too much work.