Search Engine Optimization with Angular

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.

   component: AngularComponent,
      path: "",
      data: {
      title: "Page Title",
      metatags: {
            description: "Page Description or some content here",
            keywords: "some, keywords, here, separated, by, a comma"

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 { 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 ( &&["title"]) {
          this.titleService.setTitle(["title"] + " | App Name");
          let tags =["metatags"];
          for (let tag in tags) {
            this.metaService.addTag({ name: tag, content: tags[tag] });
        } else {

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 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))(.*)$2 [P,L]

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.

17 Replies to “Search Engine Optimization with Angular”

  1. Thank you very much for your helpful post.
    Why we need to add meta tags to each page separately? Can’t we add meta tags to index.html?

    1. It varies from website to website. If your website has common met tags then its fine but if they are different, then you have to put one per each page. Also, Google might take offense to having similar keywords for each page and penalize you for it.

  2. I recently deployed an Angular5 application that exposes about 40.000 pages of content. I am not doing any server-side rendering whatsoever, and it now actually ranks better than the website it replaced (which was a completely server-rendered webforms application). Google search console also clearly demonstrates that the number of indexed pages went up dramatically (to about 90% of the pages that are listed in my sitemap files).

    I am not saying that server rendering is useless, but most articles state that it is required for angular applications, which is simply not true.

    1. Hi Davy, I appreciate your feedback as it will be useful to someone reading this. While Google does an impressive job as illustrated by your experience other search engines and bots like twitter and facebook’s are terrible with SPA. While you may be having success with Google I still will advice you to consider SSR or Pre-Rendering to serve to other non advanced search engine and social media bots. I wrote this article from experiencing issue with both facebook and twitter bots, Google i would not complain much about.

    2. @Davy since you’re not doing any serverside rendering what are you doing to add things like title and other meta tags to describe you various pages? Are you using Open Graph or Twitter Card stuff?

    3. Hello, Davy!

      This 40.000 page app serves static or dynamic content?

      I’m currently building an Angular 5 app that have the same mechanics as an ecommerce, and some of my pages, as product details, are populated client-side from a http post request. My app routes (angular router) are also different from the request routes, these ones receiving an object with properties (from Angular route params) in it’s headers and returning also an object that populates the page client-side.

      I’d like to know if it’s possible to make this kind of strategy SEO friendly. Do you have any knowledge about this?


    4. Hey Davy,

      So you are saying that Angular don’t need any server rendering? Google will scan/index data anyways?

  3. Thanks a bunch – really nice.

    I use the data feature and traversing the router states like you do, to automatically create breadcrumbs.

  4. Love your posts! There is so much to learn an to gain from! Thank you very much for your efforts. Please don´t stop educating the community. Best, Gulvar from Germany

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.