How to Integrate Yoast SEO with Angular in a Headless WooCommerce Setup, Including robots.txt...

Discussão em 'Angular' iniciado por Mohamed Sabry, Maio 5, 2025.

  1. I’m building a headless WooCommerce website with WordPress as the backend and Angular as the frontend. I’m using Yoast SEO on WordPress to manage SEO metadata (e.g., titles, meta descriptions, schema markup) and woocommerce RESTAPI to fetch this data. My Angular app uses Angular Universal for Server-Side Rendering (SSR) to ensure search engines can crawl the content properly.

    I’ve implemented an SeoService in Angular to dynamically apply Yoast SEO metadata (e.g., title, meta description, Open Graph tags, schema markup) based on the products and categories responses. Below is a simplified version of my SeoService:


    import { Injectable } from '@angular/core';
    import { Meta, Title } from '@angular/platform-browser';
    import { DomSanitizer, SafeHtml } from '@angular/platform-browser';

    @Injectable({
    providedIn: 'root',
    })
    export class SeoService {
    constructor(
    private titleService: Title,
    private metaService: Meta,
    private sanitizer: DomSanitizer
    ) {}

    applySeoTags(data: any, fallbackData: { title?: string; description?: string; image?: string; pageUrl?: string } = {}): SafeHtml | null {
    let schemaHtml = null;
    const pageUrl = fallbackData.pageUrl || window.location.href;

    if (data?.yoast_head_json) {
    const yoastJson = data.yoast_head_json;

    // Title
    this.titleService.setTitle(yoastJson.title || fallbackData.title || 'Default Title');

    // Meta Description
    if (yoastJson.description) {
    this.metaService.updateTag({ name: 'description', content: yoastJson.description });
    } else if (fallbackData.description) {
    this.metaService.updateTag({ name: 'description', content: this.stripHtml(fallbackData.description) });
    }

    // Canonical
    if (yoastJson.canonical) {
    this.metaService.updateTag({ rel: 'canonical', href: yoastJson.canonical });
    } else {
    this.metaService.updateTag({ rel: 'canonical', href: pageUrl });
    }

    // Schema Markup (simplified)
    if (yoastJson.schema) {
    schemaHtml = this.sanitizer.bypassSecurityTrustHtml(JSON.stringify(yoastJson.schema));
    }
    } else {
    // Fallback
    this.titleService.setTitle(fallbackData.title || 'Default Title');
    this.metaService.updateTag({ rel: 'canonical', href: pageUrl });
    }

    return schemaHtml;
    }

    private stripHtml(html: string): string {
    return html?.replace(/(<([^>]+)>)/gi, '') || '';
    }
    }

    My Questions

    robots.txt Handling:


    Yoast SEO generates a robots.txt file on WordPress (accessible at https://my-wordpress-site.com/robots.txt). Since my frontend is served via Angular, how should I ensure search engines access this file when visiting https://my-angular-site.com/robots.txt? Should I: Proxy requests for /robots.txt to WordPress using Express in Angular Universal? Create a static robots.txt file in Angular’s src folder and serve it from there? What’s the best practice for a headless setup?

    What is the best way to create the Robot.txt ? to create in on Angular ? or use the Yoast's (Angular has different routes ! )

    Sitemap Handling:


    Yoast generates a sitemap at https://my-wordpress-site.com/sitemap_index.xml. How can I make this sitemap accessible at https://my-angular-site.com/sitemap.xml? Should I proxy it like robots.txt, and how do I ensure the sitemap URLs point to Angular (e.g., https://my-angular-site.com/product/123) instead of WordPress?

    Btw , i'm using REST API to call the products and categories from Woocommrece , so what's the best way to use the Sitemap ??

    Schema Markup in :


    My SeoService returns schema markup as SafeHtml, which I’m adding to a using [innerHTML]. This doesn’t seem right since schema should be in as . How can I safely add schema to and remove it in ngOnDestroy to avoid duplication?

    SSR Considerations:


    Are there specific considerations for ensuring meta tags and schema markup are included in the pre-rendered HTML with Angular Universal? My current code updates tags in the browser, but I’m unsure if it works correctly on the server side.


    this is my first time

    Continue reading...

Compartilhe esta Página