Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add ld+json script tag in client-side React

Tags:

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!

like image 217
Ashish Shetty Avatar asked May 29 '18 13:05

Ashish Shetty


2 Answers

For me, React Helmet works well.

<Helmet>     <script className='structured-data-list' type="application/ld+json">{structuredJSON}</script> </Helmet>  

Where structuredJSON is something like result of such function:

export const structuredDataSingle = (prod, imgPath, availability) => {      let data = {         "@context": "http://schema.org/",         "@type": "Product",         "name": `${prod.title}`,         "image": prod.images.map((item) => imgPath + item),         "description": prod['description'],         "url": location.href,         "offers": {             "@type": "Offer",             "priceCurrency": `${prod['currency'] || "₴"}`,             "price": prod['price'] ? `${parseFloat(prod['price'])}` : 0,             "availability": `${availability}`,             "seller": {                 "@type": "Organization",                 "name": "TopMotoPro"             }         }     };      // brand     if(prod['brand']) {         data['mpn'] = prod['brand'];         data['brand'] = {             "@type": "Thing",             "name": `${prod['brand']}`         };     }      // logo     if(prod['logo']){         data['logo'] = imgPath + prod['logo'];     }      return JSON.stringify(data); }; 
like image 117
Дмитрий Дорогонов Avatar answered Sep 19 '22 13:09

Дмитрий Дорогонов


You can simply render it dangerously

<script type='application/ld+json' dangerouslySetInnerHTML={ { __html: `{ "@context": "http://schema.org", "@type": "LocalBusiness", ... }`}} /> 
like image 23
Shivam Avatar answered Sep 19 '22 13:09

Shivam