Search engine optimization with Angular 9

07/03/20 dannyVersion Française

What are we going to do ?

We will use Google's Lighthouse test tool to test our application.
We will use the Angular version 9.0.5 javascript framework.

This is Step 9 of our  Angular guide which will allow us to obtain a PWA Web Application.

All created sources are indicated at the end of the tutorial.

The application is at the following address


Before you start

The application we are going to test uses the following features

  • Routing
  • Lazy loading
  • Bootstrap
  • Components
  • Services
  • Server side rendering
  • HttpClient
  • Transfer state
  • Progressive Web App

We need to install our Angular application on a server (or virtual machine).

Note
The deployment of this application must be done on a server using the Https protocol.
In this case, you must acquire a corresponding SSL certificate.


Lighthouse

Lighthouse is an extension of Chrome that will allow us to perform multiple audits

  • Performance
  • Accessibility
  • Best practices
  • SEO


Lighthouse is available in Chrome by activating development tools
We must use Ctrl + Maj + J or F12 then select the Audit tab
Run the test with the Run audits button


The result obtained is the following.


Modifications

The audit tests show us a number of areas for improvement.
We will solve them to improve the results obtained.

  • Add 2 robots.txt and sitemap.xml files
  • Edit the angular.json file
  • Add meta tags for SEO
  • Edit the home.component.ts file

Sitemap

We will create the following files

  • Robots.txt
  • Sitemap.xml


The sitemap.xml file can be obtained by going to the sitemap generation site
https://www.xml-sitemaps.com

The robots.txt file is a standard file
These 2 files will be adapted to suit your website and its address (just replace www.wosiris.com by www.mysite.com)
Finally, it will be necessary to modify the file angular.json to take into account these files.

src/robots.txt
User-agent: *
Disallow:
Sitemap: https://angular.ganatan.com/sitemap.xml
src/sitemap.xml
<?xml version="1.0" encoding="UTF-8"?>
<urlset
      xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9
            http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">
<!-- created with Free Online Sitemap Generator www.xml-sitemaps.com -->


<url>
  <loc>https://angular.ganatan.com/</loc>
  <lastmod>2020-02-09T07:09:34+00:00</lastmod>
  <priority>1.00</priority>
</url>
<url>
  <loc>https://angular.ganatan.com/about</loc>
  <lastmod>2020-02-09T07:09:34+00:00</lastmod>
  <priority>0.80</priority>
</url>
<url>
  <loc>https://angular.ganatan.com/contact</loc>
  <lastmod>2020-02-09T07:09:34+00:00</lastmod>
  <priority>0.80</priority>
</url>
<url>
  <loc>https://angular.ganatan.com/signin</loc>
  <lastmod>2020-02-09T07:09:34+00:00</lastmod>
  <priority>0.80</priority>
</url>
<url>
  <loc>https://angular.ganatan.com/template-driven-forms</loc>
  <lastmod>2020-02-09T07:09:34+00:00</lastmod>
  <priority>0.80</priority>
</url>
<url>
  <loc>https://angular.ganatan.com/chartjs</loc>
  <lastmod>2020-02-09T07:09:34+00:00</lastmod>
  <priority>0.80</priority>
</url>
<url>
  <loc>https://angular.ganatan.com/components</loc>
  <lastmod>2020-02-09T07:09:34+00:00</lastmod>
  <priority>0.80</priority>
</url>
<url>
  <loc>https://angular.ganatan.com/services</loc>
  <lastmod>2020-02-09T07:09:34+00:00</lastmod>
  <priority>0.80</priority>
</url>
<url>
  <loc>https://angular.ganatan.com/httpclient</loc>
  <lastmod>2020-02-09T07:09:34+00:00</lastmod>
  <priority>0.80</priority>
</url>
<url>
  <loc>https://angular.ganatan.com/directives</loc>
  <lastmod>2020-02-09T07:09:34+00:00</lastmod>
  <priority>0.80</priority>
</url>
<url>
  <loc>https://angular.ganatan.com/pipes</loc>
  <lastmod>2020-02-09T07:09:34+00:00</lastmod>
  <priority>0.80</priority>
</url>
<url>
  <loc>https://angular.ganatan.com/observables</loc>
  <lastmod>2020-02-09T07:09:34+00:00</lastmod>
  <priority>0.80</priority>
</url>
<url>
  <loc>https://angular.ganatan.com/modal</loc>
  <lastmod>2020-02-09T07:09:34+00:00</lastmod>
  <priority>0.80</priority>
</url>
<url>
  <loc>https://angular.ganatan.com/reactiveform</loc>
  <lastmod>2020-02-09T07:09:34+00:00</lastmod>
  <priority>0.80</priority>
</url>
<url>
  <loc>https://angular.ganatan.com/templatedriven</loc>
  <lastmod>2020-02-09T07:09:34+00:00</lastmod>
  <priority>0.80</priority>
</url>


</urlset>
angular.json
"options": {
  "outputPath": "dist/browser",
  "index": "src/index.html",
  "main": "src/main.ts",
  "polyfills": "src/polyfills.ts",
  "tsConfig": "tsconfig.app.json",
  "assets": [
    "src/favicon.ico",
    "src/assets",
    "src/manifest.webmanifest",
    "src/sitemap.xml",
    "src/robots.txt"
  ],

SEO

We will use the Meta service provided by angular to use and add meta tags.
The file called when launching the first page is home.component.ts


After modifications, the source code obtained will be the following.

src/app/modules/general/home/home.component.ts
import { Component, OnInit } from '@angular/core';
import { Meta, Title } from '@angular/platform-browser';
import { environment } from '../../../../environments/environment';

@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.css']
})
export class HomeComponent implements OnInit {

  name = environment.application.name;
  angular = environment.application.angular;
  bootstrap = environment.application.bootstrap;
  fontawesome = environment.application.fontawesome;

  features: any;

  constructor(
    private meta: Meta,
    private titleService: Title) {
    this.features =
      [
        {
          name: 'Template Driven Forms',
          description: 'Build an Angular form with a component and template',
          icon: 'far fa-file-alt',
          link: 'template-driven-forms'
        },
        {
          name: 'Chart.js',
          description: 'Simple yet flexible JavaScript charting for designers & developers',
          icon: 'fa-share-alt-square',
          link: 'chartjs'
        },
        {
          name: 'Components',
          description: 'Define and control views',
          icon: 'fa-share-alt-square',
          link: 'components'
        },
        {
          name: 'Services',
          description: 'A great way to share information among classes',
          icon: 'fa-address-card',
          link: 'services'
        },
        {
          name: 'HttpClient',
          description: 'HttpClient',
          icon: 'fa-comment-alt',
          link: 'httpclient'
        },
        {
          name: 'Directives',
          description: 'Change the appearance or behavior of a DOM element',
          icon: 'fa-text-width',
          link: 'directives'
        },
        {
          name: 'Pipes',
          description: 'Write display-value transformations',
          icon: 'fa-code',
          link: 'pipes'
        },
        {
          name: 'RxJS/Observables',
          description: 'Provide support for passing messages between publishers and subscribers',
          icon: 'fa-comment-alt',
          link: 'observables'
        },
        {
          name: 'modal',
          description: 'Add dialogs to your site',
          icon: 'fa-comment-alt',
          link: 'modal'
        },
        {
          name: 'Reactiveform',
          description: 'Create Reactive Form',
          icon: 'fa-comment-alt',
          link: 'reactiveform'
        },
        {
          name: 'Template Driven Form',
          description: 'Create Template Driven Form',
          icon: 'fa-comment-alt',
          link: 'templatedriven'
        },
      ];

  }

  ngOnInit() {
    this.titleService.setTitle('angular.ganatan: Une Application Web avec Angular');
    this.meta.addTag({
      name: 'angular.ganatan',
      content: 'danny ganatan'
    });
    this.meta.updateTag(
      {
        name: 'description',
        content: 'Cette application a été développée avec Angular version 9.0.5 et bootstrap 4.4.1' +
          ' Elle applique le Routing, le Lazy loading, le Server side rendering et les Progressive Web App (PWA)'
      });
  }
}

Conclusion


All that remains is to perform a new audit test to obtain the final result.