DEV Community

Avi Aryan
Avi Aryan

Posted on

Rendering JSON-LD data in NextJS and ReactJS

Rendering JSON-LD data in NextJS and ReactJS is quite straight-forward. Here are the steps involved.

  1. Organize data in a plain JavaScript Object.
  2. Serialize it using JSON.stringify.
  3. Include the data in the script tag using dangerouslySetInnerHTML.
  4. 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">
    {&quot;@context&quot;:&quot;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)

Collapse
 
adi_kamel profile image
Kamel Adi

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?

Collapse
 
alioshr profile image
Aliosh Romano • Edited

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."

Collapse
 
fvaldes33 profile image
Franco Valdes

Big help here! Thanks for the post.

Collapse
 
acventor profile image
Roman Kosov

Many thanks! Your article helped me a lot