skip to Main Content

I have tried too many tricky ways,
such as Renderer2 or ɵDomAdapter,
the script tag is integrated well in the html,
but when loading the url with the structured-data tool of google,
the ld+json script is not rendered !

Is there a way to make google render the page after loading the component ?

2

Answers


  1. There are a couple of ways to achieve this. The code below is the best solution I have come up with. This example will also work with Angular Universal.

    import { Component, OnInit } from '@angular/core';
    import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
    
    @Component({
      selector: 'app-root',
      template: '<div [innerHTML]="jsonLD"></div>'
    })
    export class JsonLdComponent implements OnChanges {
      jsonLD: SafeHtml;
      constructor(private sanitizer: DomSanitizer) { }
    
      ngOnInit(changes: SimpleChanges) {
        const json = {
          "@context": "http://schema.org",
          "@type": "Organization",
          "url": "https://google.com",
          "name": "Google",
          "contactPoint": {
            "@type": "ContactPoint",
            "telephone": "+1-000-000-0000",
            "contactType": "Customer service"
          }
        };
    
        // Basically telling Angular this content is safe to directly inject into the dom with no sanitization
        this.jsonLD = this.getSafeHTML(json);
      }
    
      getSafeHTML(value: {}) {
        const json = JSON.stringify(value, null, 2);
        const html = `${json}`;
        // Inject to inner html without Angular stripping out content
        return this.sanitizer.bypassSecurityTrustHtml(html);
      }
    }
    

    I go into more detail in this blog post here https://coryrylan.com/blog/angular-seo-with-schema-and-json-ld

    I also took this technique and wrapped it up into a npm package to make
    it more reusable. https://github.com/coryrylan/ngx-json-ld

    Login or Signup to reply.
  2. I used this variant in Angular 9 TypeScript

    import { Component, OnInit } from '@angular/core';
    import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
    
    @Component({
        selector: 'app-schema-org',
        template: '<div [innerHTML]="jsonLD"></div>',
    })
    export class SchemaOrgComponent implements OnInit {
        jsonLD: SafeHtml;
        constructor(private sanitizer: DomSanitizer) { }
    
        ngOnInit() {
            const json = {
                '@context': 'http://schema.org',
                '@type': 'Organization',
                'url': 'https://google.com',
                'name': 'Google',
                'contactPoint': {
                    '@type': 'ContactPoint',
                    'telephone': '+1-000-000-0000',
                    'contactType': 'Customer service',
                },
            };
    
            // Basically telling Angular this content is safe to directly inject into the dom with no sanitization
            this.jsonLD = this.getSafeHTML(json);
        }
    
        getSafeHTML(value: {}) {
            const json = JSON.stringify(value, null, 2);
            const html = `<script type="application/ld+json">${json}</script>`;
            // Inject to inner html without Angular stripping out content
            return this.sanitizer.bypassSecurityTrustHtml(html);
        }
    }
    
    

    And then called it <app-schema-org></app-schema-org>

    For me the example above (https://stackoverflow.com/a/47299603/5155484) has no sense because it imports OnInit and implements OnChange and uses ngOnInit with a parameter for changes.

    So here is my working fixed example.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search