2.x
  1. Developer guides

Render Schema.org structured data as JSON-LD

The Sitecore Layout Service can return sitecore.context.schemas containing an array of ready-made JSON-LD node objects, each with its own @context and @type. Content SDK renders these into a single <script type="application/ld+json"> tag, so you don't have to hand-write structured data markup or manage serialization and escaping yourself.

Render structured data with SitecoreHead

The updated create-content-sdk-app templates include a SitecoreHead component in src/SitecoreHead.tsx. It groups the scripts, styles, and structured data rendered alongside the page layout:

  • Scripts renders the application's scripts.
  • SitecoreStyles renders the Sitecore styles.
  • JsonLdSchema renders the structured data from the page object.
  • In the Pages Router template, PageMetaTags also renders page metadata tags.

This integration is included in the nextjs, nextjs-app-router, and nextjs-app-router-cache-components templates. Their src/Layout.tsx files import SitecoreHead from the application and pass it the page object:

import SitecoreHead from 'src/SitecoreHead';

const Layout = ({ page }: LayoutProps): JSX.Element => {
  return (
    <>
      <SitecoreHead page={page} />
      {/* ...rest of layout... */}
    </>
  );
};

SitecoreHead is an application component supplied by the templates. It returns a React fragment, so it doesn't create an HTML <head> element.

Update an existing application

Updating SDK dependencies doesn't update the files generated when you created your application. If your application doesn't include this integration, add <JsonLdSchema page={page} /> to your existing layout as shown in the following section. You can also adopt the template's SitecoreHead structure by moving your existing scripts and styles into src/SitecoreHead.tsx, along with JsonLdSchema and, for Pages Router apps, PageMetaTags.

Render JsonLdSchema once per page. If SitecoreHead already includes it, you don't need to add another instance to your layout.

Render structured data with JsonLdSchema

Use the JsonLdSchema component from @sitecore-content-sdk/nextjs (or @sitecore-content-sdk/react) and pass it your page object:

import { JsonLdSchema } from '@sitecore-content-sdk/nextjs';

const Layout = ({ page }: LayoutProps): JSX.Element => {
  return (
    <>
      <JsonLdSchema page={page} />
      {/* ...rest of layout... */}
    </>
  );
};

JsonLdSchema accepts the following props:

PropTypeDescription
pagePage | nullPage object, for example props.page on a Sitecore page component.

The component is framework-agnostic and doesn't need to live inside <head> for its structured data to be discovered by crawlers, so you can render it anywhere in the tree — nested inside next/head's <Head> in a Pages Router layout, or directly in a Next.js App Router Server Component.

JsonLdSchema renders nothing in the following cases:

  • There are no schemas on page.layout.sitecore.context.schemas.
  • page.mode.isNormal is false — for example while in Pages/Experience Editor, Preview, or Design Library — so structured data isn't injected around unpublished or editing chrome.

Schema serialization

All schema node objects from sitecore.context.schemas are serialized into a single script as one JSON array, rather than one <script> tag per schema. Entries that aren't valid objects (null, undefined, arrays, or other non-object values) are filtered out before serialization.

Note

The serialized JSON is escaped so that characters such as <, >, &, and / can't be used to break out of the <script> tag (for example, via a </script> sequence embedded in a field value). This doesn't change the data and only affects how it's embedded in the HTML response.

Using getJsonLdSchemas directly

For rendering layers other than React (or for custom output), use the framework-agnostic getJsonLdSchemas function from @sitecore-content-sdk/content/layout (also re-exported from @sitecore-content-sdk/nextjs):

import { getJsonLdSchemas } from '@sitecore-content-sdk/content/layout';

const script = getJsonLdSchemas(context.schemas);

getJsonLdSchemas returns an HTMLScript object, or null if there are no valid schemas to render:

type HTMLScript = {
  [key: string]: unknown;
} & Pick<HTMLScriptElement, 'type'> & {
    innerHTML: string;
  };

innerHTML is already escaped and safe to assign directly, for example via dangerouslySetInnerHTML in React.

If you have suggestions for improving this article, let us know!