Rendering JSON-LD data in NextJS and ReactJS is quite straight-forward. Here are the steps involved.
- Organize data in a plain JavaScript Object.
- Serialize it using
JSON.stringify
. - Include the data in the
script
tag usingdangerouslySetInnerHTML
. - Optional but recommended - Attach a key.
The first step is creating the JSON Object. I used this in GoRemote which is a job-listing site. Here is the function which creates a job schema given the job
object. It returns a simple JavaScript object.
function makeJobSchema(job) {
const desc = stripHTML(job.description)
return {
// schema truncated for brevity
'@context': 'http://schema.org',
'@type': 'JobPosting',
datePosted: job.postedAt,
description: desc,
title: job.title,
image: job.company.logo,
workHours: 'Flexible',
validThrough: addDaysToDate(job.postedAt, 60),
hiringOrganization: {
'@type': 'Organization',
name: job.company.name,
sameAs: job.company.website || null,
logo: job.company.logo,
},
}
}
The next step is to serialize this object using JSON.stringify
. Once serialized, we insert it in a script
tag using dangerouslySetInnerHTML
. Here is how the code looks like.
export default function JobSchema({ job }) {
return (
<script
key={`jobJSON-${job.id}`}
type='application/ld+json'
dangerouslySetInnerHTML={{ __html: JSON.stringify(makeJobSchema(job)) }}
/>
)
}
Now, you might question, why do we use dangerouslySetInnerHTML
? Why not insert the serialized object as a string? Because if we do that, React treats it as HTML and so HTML-escapes the text. The output then looks like this.
<script type="application/ld+json">
{"@context":"http:...
</script>
This won’t work with bots that will crawl the page for this metadata. In other words, we don’t want to HTML-escape the text within these script
tags. So, that’s why we use dangerouslySetInnerHTML
.
Another question would be why do you need to add a key
? It’s not needed but it’s a good-to-have to avoid the situation where you have multiple JSON-LD’s for a single entity. A key
makes sure that only one such instance is included in the rendered page.
Well, there you have it.
Once you have the page running, you can use ngrok to expose your localhost online and Google’s structured data testing tool to make sure everything works as expected.
This article was posted on Avi Aryan's Blog.
Top comments (4)
Hey Avi!
Thanks for this! It's super straightforward and helpful.
I do have an additional (probably dumb) question.
How would you go about implementing this on a website? Would you just insert the entire chunk of code on the page in question?
Hello there!
Could you please explain what is this
job.description
obj instance?Are you referring to this?
schema.org/description
Like, for instance, on schema.org/Book, it would be the
description
instance, with the description: " A description of the item."Big help here! Thanks for the post.
Many thanks! Your article helped me a lot