2

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
  • I’d guess that Google’s SDTT simply doesn’t execute JavaScript. Or do you have an example where it works? Commented Oct 19, 2017 at 22:15
  • In another project it works fine with Renderer2, link , Google is parsing the injected js script very well .. Commented Oct 20, 2017 at 17:39

3 Answers 3

3

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.

Sign up to request clarification or add additional context in comments.

1 Comment

this insert and div and not a script tag
0

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

3 Comments

Can we add hide this div do not show on webpage <div [innerHTML]="jsonLD"></div>? Will it work?
Here we are expecting script not the div
this insert and div and not a script tag
0

For Angular v20.1:

import { ChangeDetectionStrategy, Component, computed, inject, input } from '@angular/core';
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';


@Component({
  selector: 'app-schema-org',
  template: '<div [innerHTML]="jsonLd()"></div>',
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class SchemaOrgComponent {
  private readonly sanitizer = inject(DomSanitizer);

  public readonly value = input<unknown>();


  public readonly jsonLd = computed<SafeHtml>(() => {
    const rawJson = JSON.stringify(this.value(), null, 2);

    const escaped = rawJson
      .replace(/<\/script/gi, '<\\/script')
      .replace(/<!--/g, '\\u003C!--');

    const html = `<script type="application/ld+json">${escaped}</script>`;

    return this.sanitizer.bypassSecurityTrustHtml(html);
  });
}

Verfied serve and build modes.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.