---
title: "Render Schema.org structured data as JSON-LD"
slug: "render-schema-org-structured-data-as-json-ld"
abstract: "Render structured data configured in SitecoreAI as JSON-LD in Content SDK Angular apps."
---
# Render Schema.org structured data as JSON-LD

JavaScript Object Notation for Linked Data (JSON-LD) provides structured data that helps search engines understand your page content. Content SDK for Angular can render the [Schema.org](https://schema.org/) schemas configured in SitecoreAI as a script in the document head.

The Layout Service exposes resolved schemas in `sitecore.context.schemas`. The SDK's `ScJsonLdSchemaComponent` reads this array from `page.layout.sitecore.context.schemas` and renders it during server-side rendering (SSR). It also updates the script during client-side navigation.

## Before you begin

To configure and display JSON-LD, you need:

- A headless Sitecore Experience Accelerator (SXA) site with access to its items and templates in the Content Editor.
- Compatible Content SDK packages that export `ScJsonLdSchemaComponent` from `@sitecore-content-sdk/angular`.
- An Angular rendering host that receives the full `Page` object, including its layout and page mode.

## Configure schemas in SitecoreAI

Follow [Configure JSON-LD schemas](https://doc.sitecore.com/sai/en/developers/sitecoreai/content-modeling-and-presentation/search-engine-optimization--seo-/configure-json-ld-schemas.html) to create the site's **Schema** container and configure any of the following:

- Page schemas that map fields on a page template to schema properties.
- Rendering schemas that map fields on a rendering's data source template to schema properties. Each rendering instance must have **Include in schema** enabled.
- Site schemas that provide values shared across the site, such as an organization's name or URL.

The SDK renders the resolved data; it doesn't create the mappings or generate schemas automatically. Review the [configuration limitations](https://doc.sitecore.com/sai/en/developers/sitecoreai/content-modeling-and-presentation/search-engine-optimization--seo-/configure-json-ld-schemas.html#limitations) before choosing schema types and properties.

## Render JSON-LD in your application

The Angular app template includes `ScJsonLdSchemaComponent` in `src/app/shared/layout.component.ts`. Apps generated from a template that includes this component require no additional rendering code.

To add the component to an existing app:

1. Update `@sitecore-content-sdk/angular` and its related SDK dependencies to compatible versions that include the component.
2. In `src/app/shared/layout.component.ts`, import `ScJsonLdSchemaComponent`, add it to the component's `imports`, and pass the current page to it:

   ```ts
   import { Component, input } from '@angular/core';
   import {
     Page,
     ScJsonLdSchemaComponent,
   } from '@sitecore-content-sdk/angular';

   @Component({
     selector: 'app-layout',
     imports: [ScJsonLdSchemaComponent],
     template: `
       <sc-json-ld-schema [page]="page()" />
       <!-- Keep your existing layout and placeholders here. -->
     `,
   })
   export class LayoutComponent {
     readonly page = input.required<Page>();
   }
   ```

   When adapting this example, retain your existing component imports, layout markup, and other layout logic.

3. Remove custom JSON-LD rendering code that duplicates the schemas now rendered by the component.

`ScJsonLdSchemaComponent` accepts one input:

| Input  | Type                        | Description                                                                                      |
| ------ | --------------------------- | ------------------------------------------------------------------------------------------------ |
| `page` | `Page \| null \| undefined` | The current page. The full object is required because rendering depends on `page.mode.isNormal`. |

The component manages a script in the document head rather than rendering visible page content. Its position in the layout template doesn't determine the script's position in the document.

### Script output and lifecycle

The SDK serializes all resolved schemas as a JSON array in one script, even when there is only one schema. For example, an organization schema produces:

```html
<script data-sc-json-ld="" type="application/ld+json">[{"@context":"https:\u002f\u002fschema.org","@type":"Organization","name":"Acme"}]</script>
```

The script has the following behavior:

- It appears only in normal mode, when `page.mode.isNormal` is `true`. The SDK removes it in editing, preview, and Design Library modes.
- The SDK updates it when the page input changes and removes it when there are no schemas or on component destruction.
- It escapes `<`, `>`, `&`, `/`, U+2028, and U+2029 as Unicode sequences for safe embedding in a script element. JSON parsers read these sequences as their original characters.
- It uses the `data-sc-json-ld` attribute to identify the managed script. The SDK leaves other JSON-LD scripts without that attribute unchanged.

> [!note]
> SitecoreAI can resolve schemas in editing mode, but the Angular component doesn't render them in that mode. Verify the script on a page in normal mode, not in Pages or preview.

## Use the JSON-LD service

For a custom layout or other code that doesn't use the component, inject `JsonLdSchemaService` from `@sitecore-content-sdk/angular`:

| Method                             | Description                                                                      |
| ---------------------------------- | -------------------------------------------------------------------------------- |
| `apply(page?: Page \| null): void` | Adds, updates, or removes the managed script based on the page mode and schemas. |
| `clear(): void`                    | Removes the managed JSON-LD script.                                              |

When using the service directly, call `apply()` when the page changes and `clear()` during the owning component's destruction. Use one component or service owner for the active page to avoid conflicting updates.

## Verify the output

To check your configuration:

1. Request Layout Service data for a page with configured mappings. Check that `sitecore.context.schemas` contains the expected schema types, properties, and values.
2. Request the page in normal mode from the SSR server. Inspect the returned HTML for a script with `type="application/ld+json"` and the `data-sc-json-ld` attribute.
3. Navigate to another page in the browser. Confirm that the SDK updates the script or removes it if the new page has no schemas.
4. Validate the rendered structured data with the [Schema Markup Validator](https://validator.schema.org/) and, for Google search features, the [Rich Results Test](https://search.google.com/test/rich-results).

If `schemas` is absent from the Layout Service response, check the site's **Schema** container, template mappings, and, for rendering schemas, the data source and **Include in schema** parameter.

The component serializes the data but doesn't validate it against Schema.org or search-engine requirements. Configure the properties required for your schema type and validate the final rendered page, not only the Layout Service response.
