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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.