Skip to the main content
SEOAudit
← Back to all articles
Technical SEO

JSON-LD structured data: what an ordinary website needs

SEOAudit7 min read

JSON-LD structured data is a block of JSON on your page that tells search engines, in a machine-readable form, what the page is: an article, an organization, a breadcrumb trail or a set of questions and answers. An ordinary website needs only a handful of types, and each takes ten or twenty lines. This guide shows which ones, with code you can adapt.

Markup does not replace good content and does not promise rankings or a rich result. It helps a search engine understand the page without guessing. Whether Google shows anything extra in the results is Google's decision, and there are no guarantees.

What structured data is and why it matters

Structured data describes the content of a page using the shared vocabulary at schema.org. Instead of inferring from the layout that "Jane Smith" is the author and "24 October 2026" is the publication date, a search engine reads those facts from a dedicated block and compares them with the visible text.

In practice markup gives you three things:

  • clarity: the entities on the page (organization, article, navigation) are named outright instead of being deduced from context;
  • compatibility with possible rich results: when a page meets the requirements, a search engine may show more than a blue link;
  • consistency: when every page describes the author, publisher and dates the same way, the site is easier to maintain and audit.

What markup does not do: it does not lift a page in the results on its own, it does not repair weak content, and it does not replace the basic technical checks such as crawlability and a correct canonical. Eligibility for a rich result is decided by Google and is never guaranteed, even when the code is flawless. The Google introduction to structured data gives the overview.

Formats and where the markup goes

Structured data can be written in three formats: JSON-LD, microdata and RDFa. Google recommends JSON-LD, for a practical reason. Microdata is woven into HTML tags, so any template change can break it. JSON-LD sits in a separate block and does not depend on the page structure.

A block looks like this:

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "WebPage",
  "name": "Example page",
  "url": "https://example.com/page"
}
</script>

You can place it in the head or in the body; both work. A few rules worth remembering:

  • @context is always https://schema.org;
  • @type names the entity type: Organization, BlogPosting, BreadcrumbList;
  • every URL is absolute, with https:// and the domain;
  • the content must be valid JSON: straight quotes, no trailing commas, no comments;
  • a page may carry several blocks, or one block with an @graph array.

A script of type application/ld+json is never executed by the browser, it is only data. That is why such blocks normally need no special allowance in a content security policy. The policy itself is covered in the article on security headers and SEO.

Which types an ordinary site needs

The schema.org vocabulary is huge, but a company site, a blog or a small service almost never needs hundreds of types. A sensible minimum looks like this:

TypeWhere it goesWhat it is for
Organizationhome pagename, site address, logo, official profiles
WebSitehome pagesite name and address, link to the publisher
BreadcrumbListinner pagespath from the home page to the current page
BlogPosting or Articleblog postsheadline, dates, author, publisher, image
FAQPagepages with visible questionsquestion and answer pairs

Other types are for pages that really are that thing. Product belongs on a product page, LocalBusiness on a business with a physical address, SoftwareApplication on an app page, VideoObject on a page built around a video. Adding them "just in case" to pages with other content is not allowed: Google's policies require the markup to match what the user sees.

The same applies to reviews and ratings. Invented reviews, or reviews a business writes about itself, break the rules and can cost you eligibility for rich results. If there are no real reviews on the page, there is no review or rating markup either. The full requirements are in Google's structured data policies.

Organization and WebSite on the home page

On the home page it is convenient to describe the organization and the site in one @graph block. Each node gets an @id, and other pages refer to it instead of copying the data.

{
  "@context": "https://schema.org",
  "@graph": [
    {
      "@type": "Organization",
      "@id": "https://example.com/#organization",
      "name": "Example Studio",
      "url": "https://example.com/",
      "logo": "https://example.com/images/logo-512.png",
      "sameAs": ["https://www.linkedin.com/company/example"]
    },
    {
      "@type": "WebSite",
      "@id": "https://example.com/#website",
      "url": "https://example.com/",
      "name": "Example Studio",
      "inLanguage": "en",
      "publisher": { "@id": "https://example.com/#organization" }
    }
  ]
}

The sameAs field should point only to real profiles that belong to you. If you have none, leave the field out. The logo must be reachable at the stated address and be a large, clear file. Logo requirements are described in Google's Organization documentation.

On a multilingual site, inLanguage matches the language of the page that carries the block. How to connect the language versions to each other is covered in the hreflang guide.

BlogPosting and BreadcrumbList for articles

A blog post is described with BlogPosting (a subtype of Article). The minimum set of fields is the headline, dates, author, publisher and image. Dates use ISO 8601, for example 2026-10-24.

{
  "@context": "https://schema.org",
  "@type": "BlogPosting",
  "@id": "https://example.com/blog/robots-txt-guide#article",
  "headline": "How to write a robots.txt file",
  "description": "A practical guide to robots.txt rules and common mistakes.",
  "datePublished": "2026-10-24",
  "dateModified": "2026-10-24",
  "inLanguage": "en",
  "author": {
    "@type": "Organization",
    "name": "Example Studio",
    "url": "https://example.com/"
  },
  "publisher": { "@id": "https://example.com/#organization" },
  "mainEntityOfPage": {
    "@type": "WebPage",
    "@id": "https://example.com/blog/robots-txt-guide"
  },
  "image": "https://example.com/images/robots-txt-cover.png"
}

Change dateModified only when you genuinely updated the content, not on every template change. All Article fields are explained in Google's article documentation.

For navigation, add a BreadcrumbList. Each item has a position, a name and a URL, and the last item is the current page.

{
  "@context": "https://schema.org",
  "@type": "BreadcrumbList",
  "itemListElement": [
    { "@type": "ListItem", "position": 1, "name": "Home", "item": "https://example.com/" },
    { "@type": "ListItem", "position": 2, "name": "Blog", "item": "https://example.com/blog" },
    { "@type": "ListItem", "position": 3, "name": "robots.txt guide", "item": "https://example.com/blog/robots-txt-guide" }
  ]
}

The trail in the markup should match the breadcrumbs the visitor sees on the page. More detail is in the breadcrumb documentation.

On this site every article carries BlogPosting and BreadcrumbList JSON-LD.

FAQPage: when it fits and what to expect

FAQPage describes a page that contains questions with answers. The key condition: the questions and answers are visible on the page, and the answers in the markup match the visible text. Marking up hidden or different text breaks the rules.

{
  "@context": "https://schema.org",
  "@type": "FAQPage",
  "mainEntity": [
    {
      "@type": "Question",
      "name": "Does JSON-LD improve rankings?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "Not by itself. It helps search engines interpret the page, and eligibility for rich results is decided by Google."
      }
    },
    {
      "@type": "Question",
      "name": "Where do I place the JSON-LD block?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "In the head or the body of the page, as a script block of type application/ld+json."
      }
    }
  ]
}

An honest note on expectations. Since August 2023 Google shows FAQ rich results only for well-known government and health websites. For an ordinary site the markup stays valid and harmless, but an expanded result is unlikely. So write the FAQ for the reader and treat the markup as a bonus: it keeps the structured data consistent with the visible content and does no harm. The rules are in Google's FAQPage documentation.

On this site the FAQ at the bottom of each article is visible on the page, and the same FAQ is marked up in JSON-LD as FAQPage.

Common mistakes that break the markup

Most JSON-LD problems are dull and repeat across sites. These are the ones that appear most often:

  • the block does not parse as JSON: a stray comma, typographic quotes instead of straight ones, an unclosed block;
  • @context is missing, so a validator does not know which vocabulary is used;
  • relative URLs instead of absolute ones;
  • the markup describes something that is not on the page: a price without a product, an author who is not shown, reviews written by the owner;
  • duplication: the theme adds Organization to every block and a plugin adds it again;
  • stale values: a date that never changes after an edit, or an old logo.

Here is what a broken block looks like:

{
  "@type": "Organization",
  "name": "Example Studio",
  "url": "/",
  "logo": "/images/logo.png",
}

There are three errors here: no @context, relative URLs, and a comma after the last field that makes the JSON invalid. The corrected version:

{
  "@context": "https://schema.org",
  "@type": "Organization",
  "name": "Example Studio",
  "url": "https://example.com/",
  "logo": "https://example.com/images/logo-512.png"
}

If a CMS or plugin generates the markup, check the output in the page source, not the plugin settings.

How to validate the markup and what the scanner shows

Validate on several levels, because each tool answers a different question.

  1. Page source (view-source) shows what the server really returns, before any script runs. Search for application/ld+json and confirm the block is there.
  2. The Schema Markup Validator (validator.schema.org) checks the markup against the schema.org vocabulary.
  3. Google's Rich Results Test shows which rich results the markup can support and whether there are critical errors.
  4. The enhancement reports in Google Search Console collect errors and warnings across the whole site once pages have been crawled.

The free scanner from SEOAudit is passive: it reads the submitted URL and a few public supporting resources. For structured data it reports whether JSON-LD is present, whether the blocks parse as JSON, whether @context is declared and which @type values appear, and it gives deterministic hints about recommended properties for common types. It parses up to ten blocks of up to 200 KB each. The scanner does not check semantic correctness against schema.org and does not claim that a page qualifies for a rich result; the Rich Results Test is the right tool for that.

Markup is only one part of a technical SEO audit. Next to it sit crawlability, canonical tags and security, for which there is a separate security check. And if you wonder how AI assistants read your site, see the page on AI search visibility.

An ordinary site is covered by Organization and WebSite on the home page, BreadcrumbList on inner pages, BlogPosting on articles and FAQPage where the questions are visible. Write it as valid JSON with absolute URLs and an @context, then validate the result. Run the free scanner on your site to see whether your pages carry markup that can be parsed.

Frequently asked questions

Does JSON-LD improve my rankings?

Not by itself. Markup helps a search engine understand a page more precisely, but rankings depend on many factors, content above all. Eligibility for a rich result is also decided by Google and is not guaranteed, even when the code is perfect.

Can I put several JSON-LD blocks on one page?

Yes. You can add several separate blocks, or gather the nodes in one @graph array and link them with @id. What matters is that every block is valid JSON and describes real content of the page instead of repeating other blocks without a reason.

Do I need FAQPage markup on an ordinary site?

Not necessarily. Since 2023 Google shows FAQ rich results only for well-known government and health sites. If your FAQ is visible on the page you can keep the markup for consistency, but do not count on an expanded result in search.

How do I check that my markup is correct?

Use the Schema Markup Validator, the Rich Results Test and the Google Search Console reports. First open the page source and confirm the block is in the server response. The SEOAudit scanner also tells you whether your blocks parse as JSON.

Want a professional security audit?

We assess web applications and infrastructure, and can help you prepare for NIS2.