# How to add structured data to a site, whatever it is built with

Structured data is a block of JSON that tells machines what a page is: who publishes it, what it sells, who wrote it. Adding it takes an hour. The work is choosing the right types, putting the block where your platform wants it, and testing it before you forget.

Updated 2026-09-15 · Source: https://porteur.ai/guides/how-to-add-structured-data

## What it does, before you spend an hour on it

Structured data is not a ranking factor. It makes a page eligible for rich results, and it tells machines what the page is about in a form they do not have to guess. Both matter, the second one more each year, because assistants read it too.

- JSON-LD is the format Google recommends. Microdata and RDFa are still read.
- It can sit in the head or the body, and Google renders pages so a script can inject it. The answering AI crawlers do not run scripts, so put it in the server's HTML.
- Several types can live in one block, joined in an @graph.
- Markup that describes something not visible on the page is a policy violation, not a clever trick.

## Which types a product site actually needs

| Page | Type | What it earns |
| --- | --- | --- |
| Home page | Organization, WebSite | The logo beside results, the entity behind the knowledge panel |
| Product or pricing page | SoftwareApplication or Product | Price and rating in the result, when the required fields are there |
| Guides and posts | Article or BlogPosting | The author, the dates, eligibility for news surfaces |
| Any page inside a section | BreadcrumbList | The trail replaces the URL line under the result |
| A page with real questions | FAQPage | No rich result for a product site since August 2023, still read by machines |
| A step-by-step page | HowTo | Nothing since September 2023; harmless, optional |

> Start with Organization and WebSite on the home page and BreadcrumbList everywhere. That is twenty minutes and it covers what most small sites are missing.

## Where the markup goes, whatever you build with

| Platform | Where the block lives |
| --- | --- |
| WordPress | An SEO plugin writes Organization, Article and breadcrumbs for you. Add extra types with the plugin's schema panel or a snippet in the theme's header |
| Shopify | Most themes ship Product and Breadcrumb markup. Check what the theme emits before adding your own, or you will have two of everything |
| Webflow or Framer | A custom code embed in the page settings, with CMS fields interpolated into the JSON |
| Next.js, Nuxt, Astro, SvelteKit | A script tag rendered by the layout or the page component, server side, with the values from your data |
| Hugo, Jekyll, plain HTML | A partial or an include in the head, filled from the page's front matter |
| Ghost, Squarespace | Article and Organization are emitted automatically. Add anything else through the code injection settings |

Whatever the platform, the same rule applies: one block per page, rendered by the server, with the values coming from the same data that renders the visible page. Markup maintained by hand in a second place drifts within a month.

## A block you can copy and change

This is the home page of a fictional product. Two types in one graph, with the identifiers that let other pages point at the same organisation.

```html
<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@graph": [
    {
      "@type": "Organization",
      "@id": "https://yourproduct.com/#organization",
      "name": "YourProduct",
      "url": "https://yourproduct.com/",
      "logo": {
        "@type": "ImageObject",
        "url": "https://yourproduct.com/logo-512.png",
        "width": 512,
        "height": 512
      },
      "sameAs": [
        "https://x.com/yourproduct",
        "https://github.com/yourproduct"
      ]
    },
    {
      "@type": "WebSite",
      "@id": "https://yourproduct.com/#website",
      "url": "https://yourproduct.com/",
      "name": "YourProduct",
      "publisher": { "@id": "https://yourproduct.com/#organization" }
    }
  ]
}
</script>
```

The logo must be crawlable and at least 112 pixels on each side. The sameAs list is how Google connects the site to the profiles that describe the same entity.

## Generating the block without writing JSON by hand

- A generator: fill the fields for a type, copy the block, paste it into the template. Faster than remembering which fields are required, and it validates the shape as you type.
- A CMS plugin: writes the common types from what the CMS already knows. Check what it emits before adding anything yourself.
- Your own template: the right answer once a value changes often. Render the JSON from the same object that renders the page, and it can never disagree with what a reader sees.

> Whatever generates it, the values must come from the page. A rating in the markup that is not printed on the page is the violation Google names.

## Testing it, before and after you deploy

1. **Validate the syntax while you write** The Schema Markup Validator checks the JSON against schema.org without Google's extra rules. It catches a missing brace and a misspelt property.
2. **Check eligibility with the Rich Results Test** Paste the URL, not only the snippet, so the test sees the page as Google fetches it. It says which rich results the page is eligible for and which required fields are missing.
3. **Read a page's markup on the live site** After deploying, run a structured data check on the URL to confirm the block is in the served HTML and not only in your editor.
4. **Watch Search Console after the next crawl** Enhancement reports appear per type, with errors and warnings across the site. That is where a template-wide mistake shows up, which a single-page test cannot see.

## The rules that keep markup valid

- Every URL absolute, including images and item references. Relative URLs are the most common error the test reports.
- Dates in ISO 8601, and the same dates a reader sees on the page.
- Prices as numbers, with the currency in its own field. Never a string with a currency sign.
- Ratings inside their scale, and only ratings that exist on the page. A business rating itself is not shown as a rich result.
- One block per page, one type per thing. Two Organization blocks on one page is a graph nobody can read.
- When content changes, the markup changes with it, which is why it should be generated, not pasted.

## When the test says eligible and nothing appears

Eligibility is not a promise. Google decides per query whether to draw a rich result, and it takes a crawl before anything can change at all.

- Wait for the recrawl. Nothing changes in results before Google has fetched the page again.
- Check the Search Console enhancement report for that type, which shows errors the single-page test passed.
- Remember which results no longer exist: FAQ rich results for an ordinary site, HowTo results, and the sitelinks search box, all withdrawn between 2023 and 2024.
- Check the markup is in the served HTML, not only in the rendered page, if you want the AI crawlers to read it too.

A finished job looks like this: the home page carries Organization and WebSite, every inner page carries a breadcrumb trail that matches its URL, the product page carries its type with the required fields, and the Rich Results Test reports no errors on all three.

## Questions

### Does schema markup improve rankings?

Not directly. Google has said structured data is not a ranking factor. It makes a page eligible for rich results, which change how the result looks and can change the click rate, and it helps machines, including AI assistants, read what the page is about.

### Where should the JSON-LD block go, the head or the body?

Either works. The head is conventional. What matters more is that the server renders it: Google will run a script that injects it, but the crawlers behind the AI assistants do not.

### Do I need a plugin to add structured data?

No, but on a CMS a plugin saves time and keeps the values in step with the content. On a framework, rendering the JSON from the same data as the page is simpler and never drifts.

### Is FAQ schema still worth adding?

It earns no rich result for a product site since August 2023, when Google limited them to well-known government and health sites. The markup is still valid and still read by machines, so add it where the questions are real and skip it where they were invented for the markup.

### How do I test structured data?

The Rich Results Test for Google eligibility, the Schema Markup Validator for schema.org syntax, and the enhancement reports in Search Console for the site as a whole after the next crawl. The old Structured Data Testing Tool was retired in 2020.

### Can I mark up content that is not visible on the page?

No. Markup describing content a reader cannot see is a violation of Google's structured data guidelines and can cost the site its rich results. Content inside a tab or an accordion the visitor can open is fine.

## Read next

- [JSON-LD: how to write it, where to put it, how to test it](https://porteur.ai/guides/json-ld): See why Google recommends JSON-LD, where to place it, how to use one @graph, how to test with Google and schema.org, and what to fix.
- [Organization schema: the fields that feed your knowledge panel](https://porteur.ai/guides/organization-schema): Set up Organization schema to feed your logo, social profiles and knowledge panel. See the fields, a JSON-LD example, where to place it, and how to test.
- [Article schema: headline, images, dates and author, done right](https://porteur.ai/guides/article-schema): Use Article, BlogPosting or NewsArticle schema the way Google expects. Get headlines, images, dates and the author right, and test it before release.
- [The Rich Results Test: what it checks and what it does not](https://porteur.ai/guides/rich-results-test): Run Google’s Rich Results Test, read eligibility, warnings and errors, know its limits, and when to use schema.org’s validator and Search Console.
- [Breadcrumbs: the navigation, the markup, and what Google shows](https://porteur.ai/guides/breadcrumbs): Add breadcrumb navigation that helps visitors, improves internal linking and gives Google a clean trail to show in results, with JSON-LD examples.
- [Structured data](https://porteur.ai/glossary/structured-data): Structured data is schema markup that names your page type. See why it changes results, how to add JSON-LD, and how to validate it.
- [Schema markup generator](https://porteur.ai/tools/schema-generator): Build the JSON-LD for an organisation, a product, an article, a FAQ, a how-to or a breadcrumb from a form, required fields marked and every value checked.
- [Structured data checker](https://porteur.ai/tools/structured-data-checker): Read the JSON-LD on a page: every type, the rich result each can earn, the required and recommended fields it lacks, and a mended copy of each node.

Paste your URL and the free check reads your markup along with the rest of the page, and names the three findings worth your next hour. Free check: https://porteur.ai/
