Angular, SEO

Dynamically SEO meta Tags setup in angular | Dynamically add meta tags based on route in Angular

Spread the love

ANGULAR UNIVERSAL SERVER SIDE RENDERING

HOW TO DEPLOY ANGULAR UNIVERSAL TO PRODUCTION?

ADD ANGULAR UNIVERSAL TO EXISTING PROJECT

Step:1 – Setup route resolve property services

We will use route resolve property to Dynamically add meta tags based on route in Angular. Please follow the blow code format to setup Dynamically add meta tags based on route in Angular.

const routes: Routes = [
  {
    path: '',
    component: AppLayoutComponent,
    children: [
      { 
        path: 'page/:pagenum',
        loadChildren: () => import('./pages/home/home.module').then(m => m.HomeModule),
        resolve: { res: HomeRouterResolverService }, // return static info
        // resolve: { res: AppUsersRouterResolverService } // return dynamic data from API
      }

    ]
  }

];

res is the key which i have defined and it holds HomeRouterResolverService service or AppUsersRouterResolverService data

In Route Resolve property you can pass more than one Angular services to complete or resolve a step before load the route path. Call the Services that return according to your requirement meta tags or information data it may static or you can call API then after call common functionality to set SEO meta tags in your particular Angular Application page.

Step:2 – Setup your resolver services

According to your requirement you can fetch meta tags information from api as I implement in below code.

import { Injectable } from '@angular/core';
import { Router, Resolve, ActivatedRouteSnapshot } from '@angular/router';
import { map } from 'rxjs/internal/operators';
import { environment } from '@env/environment';
import { HttpClient } from '@angular/common/http';
import { SeoService } from '@shared/services/common.service';

@Injectable({ providedIn: 'root' })
export class RouterResolverService {
  constructor(private router: Router) { }
}

@Injectable({ providedIn: 'root' })
export class HomeRouterResolverService implements Resolve<any> {
  constructor(private router: Router, private _seoService: SeoService) { }

  resolve(activatedRouteSnapshot: ActivatedRouteSnapshot) {
    let seoData: any = {};
    seoData['title'] = "";
    seoData['feature_image'] = "";
    seoData['description'] = "";
    seoData['keywords'] = "";

    seoData['ecomm_prodid'] = 0;
    seoData['ecomm_pagetype'] = 'home';
    seoData['ecomm_totalvalue'] = 0;
    this._seoService.setAdMetaData(seoData);
    return true;
  }
}

@Injectable({ providedIn: 'root' })
export class AppUsersRouterResolverService implements Resolve<any> {
  constructor(private _routerResolverService: RouterResolverService, private router: Router, private http: HttpClient) { }

  resolve(activatedRouteSnapshot: ActivatedRouteSnapshot) {
    //let id = activatedRouteSnapshot.paramMap.get('id');
    let params: any = {};
    
    return this.http.post(`${environment}rolePermisssion/checkModulePermission`, params)
      .pipe(
        map((result: any) => {
          if (result.response.dataset.records.length) {

            this._seoService.setAdMetaData(seoData);
            return (result);

            // return true;
          }
          else {
            return null
          }
        })
      )
  }
}

Step:3 – Set meta tags in SEO service

Two way you can set SEO data. You have to chose any one step


1. call a different common SEO service from resolver and resolver return only true;
2. setup SEO meta tags information by return resolver data at component side

According to your need and best practice you will use any of one option.

1. call a different common SEO service from resolver and resolver return only true;

SeoService code given below please follow according to your need.

import { Injectable, ComponentFactoryResolver, Inject, RendererFactory2, Renderer2 } from '@angular/core';
import { MatSnackBar } from '@angular/material/snack-bar';
import { Overlay, OverlayRef } from '@angular/cdk/overlay';
import { LoadingComponent } from '../components/loading/loading.component';
import { SnackBarComponent } from '../components/snack-bar/snack-bar.component';
import { ComponentPortal } from '@angular/cdk/portal';
import { HttpClient } from '@angular/common/http';
import { Title, Meta } from '@angular/platform-browser';
import { DOCUMENT } from '@angular/common';
import { environment } from '@env/environment';

@Injectable({
    providedIn: 'root'
})
export class SeoService {

    public copyrightYear: any = '2021';
    private renderer: Renderer2;
    public geoLocationDetails: any = {};
    public ipAddress: any = {};

    constructor(private http: HttpClient, private titleService: Title, private metaService: Meta, @Inject(DOCUMENT) private dom: any, rendererFactory: RendererFactory2) {
        let d = new Date();
        this.copyrightYear = d.getFullYear();
        this.renderer = rendererFactory.createRenderer(null, null);
        this.getIpInfo();
    }

    setAdMetaData(ad_seo_data: any) {
        this.metaService.removeTag('description');
        this.titleService.setTitle(ad_seo_data.title);
        if (ad_seo_data.metatitle && ad_seo_data.metatitle != '') {
            this.metaService.updateTag({ name: 'title', content: ad_seo_data.metatitle });
        } else {
            this.metaService.updateTag({ name: 'title', content: ad_seo_data.title });
        }
        this.metaService.updateTag({ name: 'description', content: ad_seo_data.description });
        if (ad_seo_data.keywords && ad_seo_data.keywords != '') {
            this.metaService.removeTag('keywords');
            this.metaService.updateTag({ name: 'keywords', content: ad_seo_data.keywords });
        }
        /* Facebook */
        if (ad_seo_data.title && ad_seo_data.title != '') {
            this.metaService.updateTag({ property: 'og:title', content: ad_seo_data.title });
            this.metaService.updateTag({ property: 'twitter:title', content: ad_seo_data.title });
        }

        if (ad_seo_data.feature_image && ad_seo_data.feature_image != '') {
            this.metaService.updateTag({ property: 'og:image', content: ad_seo_data.feature_image });
            this.metaService.updateTag({ property: 'twitter:image', content: ad_seo_data.feature_image });
            this.metaService.updateTag({ name: 'twitter:image', content: ad_seo_data.feature_image });
            this.metaService.updateTag({ name: 'twitter:site', content: '@JolDao_Dot_Com' });
        }
        if (ad_seo_data.description && ad_seo_data.description != '') {
            this.metaService.updateTag({ property: 'og:description', content: ad_seo_data.description });
            this.metaService.updateTag({ property: 'twitter:description', content: ad_seo_data.description });
            this.metaService.updateTag({ name: 'twitter:description', content: ad_seo_data.description });
            this.metaService.updateTag({ name: 'twitter:card', content: 'summary_large_image' });
        }
        this.metaService.updateTag({ name: 'geo.country', content: 'US' });
        this.metaService.updateTag({ property: 'og:type', content: 'website' });
        let copyrightText = "© Copyright JolDao.Com " + this.copyrightYear;
        this.metaService.updateTag({ name: 'rights', content: copyrightText });
        this.metaService.updateTag({ name: 'referrer', content: 'no-referrer-when-downgrade' });
        this.metaService.updateTag({ property: 'og:locale', content: 'en-us' });
        this.metaService.updateTag({ property: 'fb:app_id', content: environment.firebaseConfig.FACEBOOK_APP_ID });
        this.metaService.updateTag({ property: 'og:image:width', content: '1200' });
        this.metaService.updateTag({ property: 'og:image:height', content: '630' });
        this.metaService.updateTag({ property: 'og:site_name', content: "JolDao.Com | Online Water Delivery" });
        this.metaService.updateTag({ property: 'twitter:card', content: 'summary_large_image' });
        if (!ad_seo_data['nofollow']) {
            this.metaService.updateTag({ name: 'robots', content: 'index, follow' });
        }
        if (ad_seo_data['nofollow']) {
            this.metaService.updateTag({ name: 'robots', content: 'noindex, nofollow' });
            this.metaService.updateTag({ name: 'googlebot', content: 'noindex' });
        }

        return true;
    }

    getIpInfo() {
        this.http.get('https://jsonip.com').subscribe(data => {
            this.ipAddress = data;
        });
    }
   
}



2. setup SEO meta tags information by return resolver data at component side

Active route subscriber object consume data property as well. As per you requirement you can use it. And by key I have provide in route resolver property by that key I will get the resolver data for SEO meta tags setup.

import { Component, OnInit } from '@angular/core';

import { BehaviorSubject, Subscription } from 'rxjs';
import { environment } from '@env/environment';
import { Router, ActivatedRoute } from '@angular/router';

@Component({
  selector: 'app-home',
  templateUrl: './home.component.html',
  styleUrls: ['./home.component.scss']
})
export class HomeComponent implements OnInit {
  
  constructor(
    private route: ActivatedRoute,
    private router: Router,
) { }

  ngOnInit(): void {

    this.route.data.subscribe(data => {
      console.log('Check route resolver data');
      console.log(data);

      this. setAdMetaData(data.res); // here in res key return resolver service data
    })
  }


  setAdMetaData(ad_seo_data: any) {
    this.titleService.setTitle('Home page');
    this.metaService.updateTag({ name: 'title', content: 'Home page meta title' });
    this.metaService.removeTag('description');
    this.metaService.updateTag({ name: 'description', content: 'Home page description' });
    this.metaService.removeTag('keywords');
      this.metaService.updateTag({ name: 'keywords', content: 'Home page keyword' });
  }

}

References Sites

Resolve – Angular
Angular.io Meta

Thank you for reading this article. Please like share and subscribe our Facebook page to get latest updates.


Spread the love
Tagged , , , ,

About Chandra

Technology lover. Professionally Software Developer and write some Technical Blog to help newcomer.
View all posts by Chandra →

4 thoughts on “Dynamically SEO meta Tags setup in angular | Dynamically add meta tags based on route in Angular

Leave a Reply

Your email address will not be published.