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!
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); };
You can simply render it dangerously
<script type='application/ld+json' dangerouslySetInnerHTML={ { __html: `{ "@context": "http://schema.org", "@type": "LocalBusiness", ... }`}} />
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With