Warm tip: This article is reproduced from serverfault.com, please click

Add ld+json script tag in client-side React

发布于 2018-05-29 13:21:58

I have currently build a React app. Since it's a SPA, it has a single index.html file. I want to add 2 "ld+json" script tags, i.e for reviews and bookmarks for a certain route.

I've injected the script tag in componentDidMount of that component but the Google Structured Data Testing Tool doesn't read that.

Is it because Google reads directly from index.html and since my script tags are bundled inside main.js, it cannot read it?

Is it possible to do this in client side React? Is server side rendering the only possible way to do it?

-- Detailed Explanation--- I currently want to implement a system like IMDB has i.e whenever we search for a movie in goole; the IMDB search result will show the rating of the movie in the google pages itself. To do that I've need to put a script in my index.html file

<script type='application/ld+json'>
  {
      "@context": "http://schema.org/",
      "@type": "Review",
      "itemReviewed": {
        "@type": "Thing",
        "name": "Name"
      },
      "reviewRating": {
        "@type": "Rating",
        "ratingValue": "3",
        "bestRating": "5"
      },
      "publisher": {
        "@type": "Organization",
        "name": "1234"
      }
    }
</script>

Since my app is an SPA, I cannot put this in my main index.html file.

My current approach: Suppose "/movies/inception" route renders "MovieDetail" component. So, I'm currently adding the script at the end of this component.

import React from 'react';
import JsonLd from '../path_to_JSONLD';

class MovieDetail extends React.Component {
 render(){
 let data = {
  "@context": "http://schema.org/",
  "@type": "Review",
  "itemReviewed": {
    "@type": "Thing",
    "name": "Name"
   },
    "reviewRating": {
     "@type": "Rating",
     "ratingValue": "3",
     "bestRating": "5"
    },
   "publisher": {
     "@type": "Organization",
     "name": "1234"
    }
  }
   return(
    <SOME COMPOENTS />
    <JsonLd data={data} />

 )
}

My JsonLd component

import React from 'react';

const JsonLd = ({ data }) =>
  <script
    type="application/ld+json"
    dangerouslySetInnerHTML={{ __html: JSON.stringify(data) }}
  />;

  export default JsonLd;

So, when i inspect the component; i can see the dynamically added script tag. But, in the structure testing tool "https://search.google.com/structured-data/testing-tool" . It doesnt show the schema after validation. Hence, I asked whether it can be done via client side or SSR is only solution for this where i can give an updated index.html as a response.

I hope this clears the confusion. Thanks!

Questioner
Ashish Shetty
Viewed
0
Ashish Shetty 2018-06-01 21:22:56

Solution: Used "react-meta-tags" Link : https://github.com/s-yadav/react-meta-tags

import React from 'react';
import MetaTags from 'react-meta-tags';
import JsonLd from 'path_to_jsonld';


export default class MetaComponent extends React.Component {
  render() {
   return (
    <div className="wrapper">
      <MetaTags>
        <title>{this.props.title}</title>
        <meta property="og:type" content="website" />
        <meta name="description" content={this.props.description} />
        <meta name="og:description" content={this.props.description} />
        <meta property="og:title" content={this.props.title} />
        <meta property="og:url" content={window.location.href} />
        <meta property="og:site_name" content={"content"} 
         />
        {
          this.props.jsonLd && 
            <JsonLd data={this.props.jsonLd} />
        }
      </MetaTags>
    </div>
  )
 }
}

And then I imported this component in my main component

import React from 'react';
import MetaComponent from '../path_to_Metacomponent';

class MovieDetail extends React.Component {
 render(){
let data = {
  "@context": "http://schema.org/",
  "@type": "Review",
  "itemReviewed": {
    "@type": "Thing",
    "name": "Name"
    },
"reviewRating": {
    "@type": "Rating",
    "ratingValue": "3",
    "bestRating": "5"
   },
 "publisher": {
   "@type": "Organization",
   "name": "1234"
  }
}
   return(
    <SOME COMPOENTS />
    <MetaComponent jsonLd={data} title={"abcd"} description={"xyza"} />

 )
}

What the package does is insert the script tag inside the head tag dynamically and since the script now is not bundled inside the main.js file google is able to read it from the source.