Angular Universal: Implementing Dynamic SEO for Each Page with Server-Side Data Fetching

416 views Asked by At

I am developing an Angular Universal application and aiming to implement dynamic SEO metadata for each page. To achieve this, I need to fetch data on the server side and dynamically update the SEO meta tags (e.g., title, description) based on the content fetched. Here's a detailed overview of my objective and the challenges I'm facing:

  • Implement dynamic SEO metadata for each page of my Angular Universal application.
  • Fetch relevant data on the server side to populate the SEO meta tags.

Below is a simplified version of my code:

import { Component, Inject, PLATFORM_ID } from '@angular/core';
import { isPlatformBrowser } from '@angular/common';
import { HttpClient } from '@angular/common/http';
import { ActivatedRoute } from '@angular/router';

@Component({
  selector: 'app-your-component',
  templateUrl: './your-component.component.html',
})
export class YourComponent {
  isBrowser: boolean;

  constructor(
    private http: HttpClient,
    private route: ActivatedRoute,
    @Inject(PLATFORM_ID) private platformId: any
  ) {
    this.isBrowser = isPlatformBrowser(platformId);
    if (!this.isBrowser) {
      this.fetchData();
    }
  }

  fetchData() {
    this.route.params.subscribe(params => {
      const id = params['id'];
      const name = params['name'];

      this.http.get(`your-server-api-url?id=${id}&name=${name}`).subscribe((data) => {
        // Handle the data received from the server here
        // Update SEO meta tags based on the fetched data
      });
    });
  }
}

My primary goal is to achieve dynamic SEO for each page of my Angular Universal application. I intend to fetch relevant data from the server side and use this data to dynamically update SEO meta tags such as title, description, and others. This way, search engines can index my pages accurately, and users will see meaningful results when sharing links.

  • I've confirmed that the API endpoint (your-server-api-url) is correct and accessible.
  • The route configuration in my Angular app appears to match the URL structure, and route parameters are correctly defined.
  • Server-side logs do not report any errors during the data-fetching process.

I would greatly appreciate any guidance, best practices, or suggestions on how to successfully implement dynamic SEO for each page in my Angular Universal application by fetching data on the server side. Your insights are invaluable! Thank you!

1

There are 1 answers

0
millenion On

You can do it right this way:

Dedicated Services

There are 2 main services you want to use here:

  1. Title: Use it to update the html tag

  2. Meta: Use it to update any meta tags in your Html

You can import them like that into your components:

import { Meta, Title } from "@angular/platform-browser"

Here is an implementation example that i personally use and that works perfectly for a rich case (Article). We will assume you will use it on main components in your app:

export class ArticleComponent implements OnInit, OnDestroy {

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

  ngOnInit() {
    const slug = this.route.snapshot.paramMap.get("slug")
    article: this.publicService.getArticle(slug).subscribe({
      next: (article: Article) => {
        this.article = article
        this.updateSeoTags()
      }
    })
  }

  updateSeoTags() {
    this.titleService.setTitle(this.article.title)
    /** Awesome Website meta tags **/
    this.metaService.updateTag({
      name: "description",
      content: this.article.caption,
    })

    /** OpenGraph meta tags **/
    this.metaService.updateTag({
      property: "og:title",
      content: this.article.title,
    })

    this.metaService.updateTag({
      property: "og:description",
      content: this.article.caption,
    })

    this.metaService.updateTag({
      property: "og:type",
      content: "article",
    })

    this.metaService.updateTag({
      property: "og:image",
      content: this.article.picture
    })

    this.metaService.updateTag({
      property: "og:url",
      content: this.article.canonicalUrl,
    })

    this.metaService.updateTag({
      property: "article:published_time",
      content: this.article.createdAt.toISOString(),
    })

    this.metaService.updateTag({
      property: "article:author",
      content: "Author name",
    })

    /** Twitter Card meta tags **/
    this.metaService.updateTag({
      name: "twitter:card",
      content: "summary_large_image",
    })

    this.metaService.updateTag({
      name: "twitter:site",
      content: "@YourTwitterHandle",
    })

    this.metaService.updateTag({
      name: "twitter:creator",
      content: "@YourTwitterHandle",
    })

    this.metaService.updateTag({
      name: "twitter:title",
      content: this.article.title,
    })
    this.metaService.updateTag({
      name: "twitter:description",
      content: this.article.caption,
    })
    this.metaService.updateTag({
      name: "twitter:image",
      content: this.article.picture,
    })
    this.metaService.updateTag({
      name: "twitter:image:alt",
      content: this.article.title,
    })
  }
}

Use Absolute Urls only

You need to remember using absolute urls in every url field in order to make it work properly (images too).

About Twitter/X

For twitter/X tags, i'd recommend you to check twitter/x developer docs here

Don't forget to add a Canonical Url

<link rel="canonical" href="canonicalUrl" />

There are a few way to set it through Angular, but you'd basicaly need to replicate what Meta does and apply it on a custom service named for example Link. Otherwise just inject DOCUMENT and play with it.

Check if it's working

Very simple step: Just disable your javascript in developer console, refresh the page, check the source code of the generated page and make sure everything is working as expected

Going further with Structured Data

For structured data, well that's another question.

You can still check what google says about it and what they consider valid depending on content types. They also provide a small tutorial about it and a few testing tools for it.

Google Structured data Code Lab

Some useful tools for Structured data

To pre-validate your generated structured data before pushing it to production, you can do it with this tool