How to add Schema in Next.js


3 min read

Search Engines (especially Google) work hard to understand the content of a page. You can help them by providing explicit clues about the meaning of a page, by including schema structured data.
If you need to improve the SEO of your web pages, it’s recommended to put in place structured data on your website. In this tutorial, I explain how.

What is structured data? (also called schema) is a semantic vocabulary of tags that you can add to your HTML Pages to improve how search engines read and represent your page in SERPs. vocabulary can be used with many encodings, including RDFa, Microdata, and JSON-LD.
In this article, we’ll cover how to add Structured Data using the JSON-LD format, to a website made using Next.js 13+ and App Router.

JSON-LD Format

JSON for Linking Data is a way to create a network of standards-based, machine-readable data across websites. It is a lightweight data format, easy for humans to read and write.
For example, a Party Coffee Cake blog post can be described using JSON-LD this way.
    <title>Party Coffee Cake</title>
    <script type="application/ld+json">
      "@context": "",
      "@type": "Recipe",
      "name": "Party Coffee Cake",
      "author": {
        "@type": "Person",
        "name": "Mary Stone"
      "datePublished": "2018-03-10",
      "description": "This coffee cake is awesome and perfect for parties.",
      "prepTime": "PT20M"
    <h2>Party coffee cake recipe</h2>
      <i>by Mary Stone, 2018-03-10</i>
      This coffee cake is awesome and perfect for parties.
      Preparation time: 20 minutes
The JSON-LD contains standard markups to describe the content of the article.
You can find all the markups at

Add JSON-LD to a Next.js page

First of all, create a layout.tsx (or .jsx if you prefer) for your page.
Finally define the JSON-LD and include it in the layout using the Next.js Script tag.
import Script from "next/script";
import { FAQPage, WithContext } from "schema-dts";

const jsonLd: WithContext<FAQPage> = {
  "@context": "",
  "@type": "FAQPage",
  mainEntity: [
      "@type": "Question",
      name: "Why should my password be unique?",
      acceptedAnswer: {
        "@type": "Answer",
        text: "If you use the same password for both your email account and your bank account login, an attacker only needs to steal one password to get access to both accounts, doubling your exposure. If you've used that same password for 14 different accounts, you're making the attacker's job very, very easy. You can protect yourself by using a our <a href=\"\">Secret Password Generator</a> to create unique passwords.",
  headline: "Strong Random Secrets and Password Generator",
    "Free online tool to generate random strings and passwords in various formats.",
  author: {
    "@type": "Person",
    name: "Luca Restagno",
    url: "",
  image: "",
  datePublished: "2023-12-10",
  dateModified: "2023-12-28",

export default function PasswordGeneratorLayout({
}: {
  children: React.ReactNode;
}) {
  return (
          __html: JSON.stringify(jsonLd),
I use TypeScript and I recommend using the npm package schema-dts to import the types for each structured data type.
If your web page contains multiple types, like FAQPage and Product for instance, include a <Script /> tag for each type.

Validate your page

Checking if your page is correctly formatted is crucial. Google will not index your page if the structured markup is not correct.
To do so you can use two websites. The Schema Markup Validator and the Google Rich Results Test tool.
Paste the URL of your website, and test the URL. If the markup is correct, you’ll see a page like this.
notion image


The Markup is a way to help search engines and machines in general, to understand the type of content that your webpages include.
This helps you with SEO and SERP, and helps your websites to stand up from the crowd.

Ship your startup in days and start selling.

Save weeks of coding with the #1 Next.js Startup and Chrome Extension Boilerplate. Made by a maker for makers.