Back to blog
AI Schema Generator7 min readApril 20, 2026

How to Add JSON-LD Schema Markup in Next.js and React

Implementing schema markup in React and Next.js apps has its quirks: SSR, hydration, App Router vs Pages Router. Learn the correct way to add JSON-LD in each environment without breaking hydration.


In a static HTML site, adding schema markup is trivial: paste the JSON-LD block in the <head> and you're done. In a Next.js or React application things get complicated: you have SSR, client hydration, the App Router with Server Components, the Pages Router with _document.tsx, and multiple pages with different schemas that must not interfere with each other. Doing it wrong can generate duplicate schema, hydration errors, or markup that Google doesn't detect.

Next.js App Router (Next.js 13+): the recommended approach

In the Next.js App Router, the correct place for schema is inside the page or layout component, using a <script> tag with dangerouslySetInnerHTML. Being a Server Component by default, the schema is rendered on the server and Google sees it in the initial HTML without needing to execute JavaScript.

The correct pattern is to define the schema object as a typed TypeScript constant and serialize it with JSON.stringify directly in the JSX:

  • Define the schema as a TypeScript object — typed, no risk of manual JSON syntax errors.
  • Use JSON.stringify(schema) inside dangerouslySetInnerHTML={{ __html: ... }}.
  • Place the <script> tag inside the page.tsx component of the corresponding route.
  • For global schemas (Organization, WebSite), place them in the root layout.tsx.
  • Don't use useEffect to inject the schema — it would lose SSR and Google might not detect it.

Next.js Pages Router: _document.tsx vs page component

In the Pages Router, you have two options depending on the schema type:

  • Global schemas (Organization, WebSite): add them in _document.tsx inside the <Head> — they render on all pages.
  • Page-specific schemas: add them in each page's component using the <Head> component from next/head with the <script> inside.
  • If you use next-seo or similar: many SEO libraries for Next.js include native support for JSON-LD — check the library's documentation before implementing manually.

Pure React (without Next.js): react-helmet or direct insertion

In a React SPA without SSR, schema can be added in two ways:

  • With react-helmet or react-helmet-async: allows managing the <head> declaratively per component, including <script> tags.
  • With useEffect + document.createElement: dynamically creates the script tag and adds it to the head. The problem is that the schema doesn't exist in the initial HTML — SPAs without SSR have limited schema visibility for Google.
  • Recommendation: if SEO is important, use SSR (Next.js, Remix) rather than a pure SPA.

Common schema errors in JavaScript apps

ErrorCauseSolution
Duplicate schemaSchema in layout + schema in page for the same typeCentralize: global in layout, specific in page
Schema not detected by GoogleInjected with client-side JS without SSRRender on server or use SSR/SSG
Hydration errorSchema generated dynamically with data that differs between server and clientGenerate schema with static data or ensure the initial state is the same
Invalid JSON in productionData with special characters not escaped in JSON.stringifyUse JSON.stringify — never build the JSON as a string with interpolation

How to generate the JSON-LD for your Next.js app

iRankly's AI Schema Generator produces the JSON object ready to use. Copy it, paste it as a constant in your Next.js component, and use JSON.stringify to serialize it in the script tag. The generator includes all Google-recommended fields for the selected schema type.

Try the tool for free

AI Schema GeneratorAnalyze your URLs with {tool} by iRankly. No sign-up, no credit card.

Use tool for free

Verify schema with iRankly's Schema Validator

Once implemented, verify that Google correctly detects the schema with iRankly's Schema Validator: enter the URL of the already-published page and check that the schema appears correctly parsed without errors in required fields.


Try the tool for free

Analyze your URLs with AI Schema Generator by iRankly. No sign-up, no credit card.

Use tool for free