Back to all posts

Angular SEO: How to Make Search-Friendly Pages

Posted by Abhishek Kothari on November 21, 2019
  1. SEO for conventional web applications
  2. Single Page Application (SPA) SEO
  3. Developing search-friendly pages in Angular
  4. Implementing prerendering for Angular application
  5. Validating your SEO friendly Angular SPA

Introduction to Angular Framework

Angular Framework, a structural javascript based framework for web applications, is used to create dynamic web pages with content rendered via web services. The angular framework is very developer-friendly and has been around for several years.

Applications built using Angular Framework are called Single Page Applications given the way they function. An Angular application, once loaded, renders other pages dynamically without reloading the web pages all over again. This experience is delivered with the power of the Angular javascript framework. It dynamically modifies the pages by running javascript code or by loading only the required content. This gives the user a smooth experience without waiting for a reload to happen. However, there are adverse effects on the optimization of the Angular sites for search engines.

In this article, we articulate how Angular applications need special search engine optimization treatment and provide deployment instructions.

Workings of search engine optimization algorithms

Before we address the solution, let us understand how the search engine bots actually work. Search engines around the world crawl through your websites to understand the pages and the end goal of your business. For this, the crawlers read through the metadata of the pages such as the title, description, image tags, and categories. This metadata needs to be different for every page to allow search engines to understand your business better.  

A search engine bot reaches a specific page, finds the hyperlinks on the page, reads the metadata on the page and starts traversing through the hyperlinks. It keeps repeating this process on your website until it is unable to get any new links. During this process, the bot downloads the static content of your website and understands about the page. Thus, it becomes important to maximize the details about each page in the metadata and static content.

1. SEO for conventional web applications

Search Engine Optimization (SEO) has become one of the most important investments for any online business today. In the past, the web applications being developed were fairly simple and contained mostly static pages. These pages contained all the required information pre-coded into them. As the web application development evolved, we entered an era of dynamic content rendering where the content for the web pages is stored somewhere and fetched as needed. 

There are two ways of doing this: 

  1. Server-side rendering
  2. Client-side rendering

Due to the lack of sophisticated client-side rendering frameworks in the past, server-side rendering of pages was the trend. There were numerous languages and frameworks to handle the same. For instance, PHP, Java Spring, NodeJS with Handlebars and other frameworks render the pages in advance and send only the plain HTML content to the frontend. 

This approach ensures that the page has the right meta tags and all the content rendered before it is received by the search engine crawler. Thus, the conventional web applications were practically simple when it came to SEO. However, it surely had a downside of loading time. With low-end servers, processing thousands of requests for pages became difficult for servers too. This brought into picture frontend frameworks like Angular.

2. Single Page Application (SPA) SEO

A Single Page Application is a concept where the application base layout is loaded only once and the rest of the pages and components are loaded only as needed. This is made possible with the power of Javascript that dynamically decides what content is required, fetches the data and renders it in the desired format. 

Sign up to receive articles on Angular SEO.
    

a. Benefits of a Single Page Application

Due to its dynamic nature, a Single Page Application has a lot of inherent benefits associated with it. Some of these are listed below:

  • Faster transition time once the application has loaded
  • Smoother experiences compared to a conventional web application
  • Less load on the webserver processing the pages
  • Faster development time due to sophisticated frameworks like Angular

Despite these benefits, one significant challenge with Single Page Applications is SEO. 

b. SEO challenges with a Single Page Application

As understood, Angular does not reload the pages unless explicitly asked to. Angular does support change of metadata for the pages dynamically but it completely depends on JavaScript. As discussed before, search engine crawlers do not normally entertain Javascript. This causes Angular applications to fail in rendering the right content or metadata. 

However, over the years, Angular SEO has evolved and the community has brought a solution to get around this. The solution allows us to create static pages out of Angular pages. These static pages contain the right metadata and pre-rendered content. Later in this article, we will dive into this process to understand the challenges involved and implement tractics to optimize SEO.

3. Developing search-friendly pages in Angular

Before we begin building a working Angular SEO friendly solution, let us start by creating a blank Angular JS application. 

ng new seo-friendly-app


The command creates a fresh Angular JS application where we will create a simple home page and blog page, render some content on the blog page using ButterCMS APIs and make them SEO friendly. 

Let’s start by creating pages and routes for the same. Execute the below commands in the terminal to create your home and blog pages. 

ng g c pages/home --skipTests=true
ng g c pages/blog --skipTests=true


This will create the components and import them into the
app.module.ts file. Now, add the pages to the routing module to allow us to route to these pages. Modify your app-routing.module.ts file.

import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { HomeComponent } from './pages/home/home.component';
import { BlogComponent } from './pages/blog/blog.component';
const routes: Routes = [
  {
    path: 'home',
    component: HomeComponent
  },
  {
    path:'blog',
    component: BlogComponent
  },
  {
    path:'**',
    component: HomeComponent
  }
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }


The above code maps the respective components with their routes and sets HomeComponent as the default component. Now, modify the
app.component.html file to contain only a single line of code. 

<router-outlet></router-outlet>


Finally, run the application using the below command and check to ensure that your application is set up correctly. Once the command goes through, you can hit the URL
localhost:4200 to ensure things are set up fine. You should see the text “home works!”.

ng serve


Now let us add a header that allows us to navigate through the pages. Create a header component using the below command.

ng g c header --skipTests=true


Next, modify the content of the header.component.html to contain the navigation elements. 

<div>
<a [routerLink]="['home']">Home</a>
</div><div>
<a [routerLink]="['blog']">Blog</a>
</div>


Finally, you have a complete application where you have two pages and a simple unstyled navigation that allows you to move between the pages. Now, let us analyze this application from an SEO perspective. Right-click on the browser and select “View page source”. You should be able to see how the search engine crawlers would see your page without Javascript. The code looks like the below snippet. 

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>SeoFriendlyApp</title>
  <base href="/">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
  <app-root></app-root>
<script src="runtime.js" type="module"></script><script src="polyfills.js" type="module"></script><script src="styles.js" type="module"></script><script src="vendor.js" type="module"></script><script src="main.js" type="module"></script></body>
</html>

Now, navigate to the blog page and perform the same action and notice the page content. It is similar. This includes the page title as well as body. This is because Angular modifies your DOM using javascript. 

a. Creating dynamic pages

Hereby, we managed to implement this on the static pages. Let us now render our blogs and blog content page using ButterCMS API. This will allow us to perform SEO on static as well as dynamic web content. Before starting with it, do register a free trial account with ButterCMS to be able to create dynamic content easily. 

To do this, let’s install ButterCMS plugin using NPM

npm install --save buttercms


Once installed, let’s create a service file on the path
services/butterCMS.service.ts and put in the below content inside the file.

import * as Butter from 'buttercms';
export const butterService = Butter('your_api_token');


Replace your token in the above code. This service file ensures that the token is managed globally in a single file. We can import this file wherever we need to use the ButterCMS services. Now, let us quickly implement the below code in the
blog.component.ts file to get a list of posts. 

import { Component, OnInit } from '@angular/core';
import { butterService } from '../../services/butter-cms.service';
@Component({
  selector: 'app-blog',
  templateUrl: './blog.component.html',
  styleUrls: ['./blog.component.css']
})
export class BlogComponent implements OnInit {
  posts:any[];
  constructor() {
    this.fetchPosts();
  }
  private fetchPosts() {
    butterService.post.list({
      page: 1,
      page_size: 10
    })
      .then((res) => {
        console.log('Content from ButterCMS');
        console.log(res);
        this.posts = res.data.data;
      });
  }
  ngOnInit() {
  }
}


Now, go to the browser and inspect the console output in the console. You should be able to see the list of your posts in the browser console. As you can see in the code snippet below, this demonstrates two of the posts that I have created for this tutorial. 

Now, let us render this content on the blog page. To do so, update your blog.component.html file with the below code:

<div *ngIf="posts!=undefined">
<div *ngFor="let post of posts.data">
  <hr>
  <h1>{{post.title}}</h1>
  <div [innerHTML]="post.body"></div>
</div>
</div> 

This will render the posts from your ButterCMS platform onto the webpage. Let us now understand how to set a custom title and meta tags for each page. 

b. Setting title and meta tags for Angular SEO

Angular understands this problem and already has a solution to this. To add metadata and modify the page title dynamically, all you need to do is utilize these modules from Angular. Update the code for your home.component.ts file with the below. Perform similar changes on your blog.component.ts as well. 

import { Component, OnInit } from '@angular/core';
import { Meta,Title } from '@angular/platform-browser';
@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {

  constructor(private meta: Meta,private title: Title) {
    this.meta.addTags([
      {name: 'description', content: 'Home page of SEO friendly app'},
      {name: 'author', content: 'buttercms'},
      {name: 'keywords', content: 'Angular, ButterCMS'}
    ]);
    this.setTitle('Home Page');
  }
  public setTitle( newTitle: string) {
    this.title.setTitle( newTitle );
    }
  ngOnInit() {
  }
}


Once these changes are saved, observe the title on the browser tab.  It changes dynamically as you navigate through pages. Additionally, if you inspect the code in the browser console you will see that the corresponding metadata has also been attached. However, if you check the page source the content is still the same. This means that if Javascript is permitted, we can generate a dynamic title and meta, but not without it. 

Thus, we need a way to take the content of this rendered page and send it to the user. This process is called pre-rendering of the content. There are several methods to perform pre-rendering. In the next section, we will explore one of them. 

c. Understanding the need for pre-rendering

Pre-rendering essentially means that the HTML content of the page would be compiled in advance. This would ensure that the title and metadata of the page is present when it reaches the client-side. With pre-rendering, we can expose the final HTML content to the crawler rather than exposing blank HTML. 

4. Implementing pre-rendering for Angular applications

With the upgrades in Angular, now it comes with a standardized solution to pre-rendering as well. The process is quite simple. We would leverage the Angular Universal package to support pre-rendering of the pages. To add the Angular universal package, execute the below command with the project name that you used while creating your Angular app.

ng add @nguniversal/express-engine --clientProject seo-friendly-app


This will create some files within the project and configure your project to support pre-rendering using a NodeJS server. In order to run this, execute the below command.

npm run build:ssr && npm run serve:ssr

This command compiles, builds your static pages, places them in the dist folder and serves them by running a NodeJS server. With this, we have ensured that our Angular application is built in an SEO friendly manner and all its content is dynamically rendered. 

5. Validating your SEO friendly Angular SPA

To validate the implementation, you can go to the browser and view page source for each page. Now, you will be able to see that the browser renders the exact HTML content as you would expect it to. With this, we established our implementation of a simple unstyled blog with an SEO friendly rendering on Angular framework. With ButterCMS, you can do a lot more like dynamically fetching the SEO tags, meta descriptions and even the page content itself. Interested to know more? Check out these tutorials for more.

Sign up to receive articles and tutorials on Angular SEO.
    

Related Articles