Skip to content

Instantly share code, notes, and snippets.

@paulgrieselhuber
Last active March 22, 2023 04:20
Show Gist options
  • Star 9 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save paulgrieselhuber/1966bf21c70458e058b38cda6bfb9685 to your computer and use it in GitHub Desktop.
Save paulgrieselhuber/1966bf21c70458e058b38cda6bfb9685 to your computer and use it in GitHub Desktop.
Adding Schema Data to Next.js Sites
import Head from "next/head";
import { site, siteTitle } from "../../config";
function strip(html) {
var one = html.replace(/<\/?[^>]+(>|$)/gm, "");
var two = one.replace(/[\r\n]\s*[\r\n]/gm, "");
return two;
}
const Schema = ({ post }) => {
const {
title,
blurb,
featuredImage,
date,
modified,
slug,
commentCount,
author,
ratingCount,
ratingAverage,
citations
} = post;
const published = new Date(date);
const copyrightYear = published.getFullYear();
let mediaDetails, sourceUrl;
if (featuredImage) {
sourceUrl = featuredImage.sourceUrl;
}
const citationsList = citations.map((citation, i) => {
return `{ "@type": "CreativeWork", "citation": ${JSON.stringify(
citation
)} }${i === citations.length - 1 ? "" : ","}\n`;
});
const citationsText = citationsList.join("");
const org = `{ "@id": "${site}#organization", "type": "Organization", "name":"${siteTitle}", "logo": {
"@type": "ImageObject",
"name": "${siteTitle} Logo",
"width": "230",
"height": "67",
"url": "${site}images/logo.png"
} }`;
return (
<Head>
<script type="application/ld+json">{`
{
"@context":"https://schema.org/",
"@type":"Article",
"name":"${title}",
${
ratingAverage > 4
? `"aggregateRating": {
"@type":"AggregateRating",
"ratingValue":${ratingAverage},
"reviewCount":${ratingCount}
},`
: ""
}
"about": "${blurb}",
"author": { "@type": "Person", "@id": "${site}author/${
author.slug
}", "name": "${author.name}" },
${
citationsText.length
? `"citation": [
${citationsText}
],`
: ""
}
"commentCount": ${commentCount},
"copyrightHolder": { "@id": "${site}#organization" },
"copyrightYear": ${copyrightYear},
"datePublished": "${date}",
"dateModified": "${modified}",
"description": "${blurb}",
"discussionUrl": "${site}articles/${slug}#comments",
"editor": { "@id": "${site}author/${author.slug}#author" },
"headline": "${title}",
${sourceUrl ? `"image": "${sourceUrl}",` : ""}
"inLanguage": "English",
"mainEntityOfPage": "${site}articles/${slug}",
"publisher": { "@id": "${site}#organization" },
"sourceOrganization": ${org},
"url": "${site}articles/${slug}"
}
`}</script>
</Head>
);
};
export default Schema;
@paulgrieselhuber
Copy link
Author

Assumes you have call the component with standard WP post data (plus I added some custom fields, like blurb), and have called the component via:

<Schema post={post} />

For more information: https://www.loudnoises.us/adding-schema-data-to-next-js-sites/

@jayharr-is
Copy link

jayharr-is commented Aug 9, 2019

This worked great for me, with one change: I had to use dangerouslySetInnerHTML on the script tag to avoid NextJS escaping the text inside, which threw this error in Google's Structured Data Testing Tool: Missing '}' or object member name.

@SahilMahadwar
Copy link

function strip(html) { var one = html.replace(/<\/?[^>]+(>|$)/gm, ""); var two = one.replace(/[\r\n]\s*[\r\n]/gm, ""); return two; }

what's is the use of this function?

@MohtashimAli85
Copy link

function strip is used to replace tags to only put plain text in the schema attribute for example desc:{strip(data)}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment