On-page and content

Structured Data for Small Sites: Article, FAQ, Breadcrumbs

Which structured data a small site needs, a complete JSON-LD graph to copy, what never to mark up, and the plain truth about FAQ rich results today.

Blue archive binders lined up on a shelf
Photo: Zulfugar Karimov on Pexels

Google guarantees no special display for any structured data, so treat it as labelling, not as a growth tactic. Labelling is still worth an hour on a small site. One block in a template states what each page is, who publishes it and where it sits in the site, in a form a machine can read without guessing.

What a small content site should mark up

Google recommends JSON-LD, a block of JSON in a <script type="application/ld+json"> element, over markup woven into the HTML. Its general guidelines add three limits that shape everything below: the markup must describe content visitors can actually see on the page, there is no guarantee that any markup produces a rich result, and a violation can lead to a manual action, which removes the page’s eligibility for rich results.

Within those limits, a small publisher needs few types. We recommend an Organization and a WebSite once per site, a Person for the editor if a real person stands behind the site, an Article on every guide or post, and a BreadcrumbList wherever the page shows a breadcrumb trail. Linking the nodes with @id references, instead of repeating their content, keeps one definition of each entity inside a single @graph, so the publisher’s name can never differ between two nodes.

This is what our own pages carry. Every page ships WebSite, Organization and Person nodes. Guides add Article and BreadcrumbList, and a FAQPage when the guide shows a visible FAQ block. Tool pages add a WebApplication node with a name, a URL, a category and an Offer with a price of 0, because the tools are free. We add no ratings to it, since we have no reviews to display. All of it sits in a single script element generated by the page template, so nobody has to remember to paste it.

A graph you can copy

The block below is the pattern, with placeholders. Replace example.com, the names and the dates. Every URL is absolute, the dates are in ISO 8601, and the @id values are URLs with a fragment so they never collide with a real page.

{
  "@context": "https://schema.org",
  "@graph": [
    {
      "@type": "WebSite",
      "@id": "https://example.com/#website",
      "url": "https://example.com/",
      "name": "Example Site",
      "inLanguage": "en",
      "publisher": { "@id": "https://example.com/#org" }
    },
    {
      "@type": "Organization",
      "@id": "https://example.com/#org",
      "name": "Example Site",
      "url": "https://example.com/",
      "logo": {
        "@type": "ImageObject",
        "url": "https://example.com/logo-512.png",
        "width": 512,
        "height": 512
      },
      "founder": { "@id": "https://example.com/#editor" }
    },
    {
      "@type": "Person",
      "@id": "https://example.com/#editor",
      "name": "Jane Doe",
      "jobTitle": "Network engineer",
      "sameAs": ["https://www.linkedin.com/in/example-editor/"],
      "worksFor": { "@id": "https://example.com/#org" }
    },
    {
      "@type": "Article",
      "@id": "https://example.com/guides/my-guide/#article",
      "headline": "My Guide Title",
      "description": "One sentence that matches the meta description.",
      "image": ["https://example.com/og/my-guide-en.jpg"],
      "datePublished": "2026-10-30T00:00:00.000Z",
      "dateModified": "2026-10-30T00:00:00.000Z",
      "inLanguage": "en",
      "author": { "@id": "https://example.com/#editor" },
      "publisher": { "@id": "https://example.com/#org" },
      "mainEntityOfPage": { "@id": "https://example.com/guides/my-guide/" }
    },
    {
      "@type": "BreadcrumbList",
      "itemListElement": [
        { "@type": "ListItem", "position": 1, "name": "Home", "item": "https://example.com/" },
        { "@type": "ListItem", "position": 2, "name": "Guides", "item": "https://example.com/guides/" },
        { "@type": "ListItem", "position": 3, "name": "Technical SEO", "item": "https://example.com/guides/category/technical/" },
        { "@type": "ListItem", "position": 4, "name": "My Guide Title", "item": "https://example.com/guides/my-guide/" }
      ]
    }
  ]
}

A few notes on the fields that go wrong most often. headline should match the visible H1 (heading structure explains why that line matters twice). image is an absolute URL of a real file; our share images are 1200 by 630 pixels, and the image SEO guide covers the rest of the image side. Point author at a person who really signs the page, since Google’s guidance on helpful content asks for clear author information without invented qualifications or profiles; the E-E-A-T guide goes through what that means in practice. Delete sameAs if you have no public profile to link. Change dateModified only when the content has changed.

FAQ markup: what it does now

Since 2023, Google shows FAQ rich results only for well-known government and health sites. It removed its FAQ structured data documentation in 2025. On a site like yours or ours, FAQPage markup will not produce expandable questions under the search result, and advice that promises them to ordinary sites dates from before that change.

The markup is still valid and other systems can still read it, which is the only reason we emit it on guides that show an FAQ block. If you keep or add it, the rules that matter are unchanged: the questions and answers must be visible on the page, in the same words as the markup, and written for readers first.

{
  "@context": "https://schema.org",
  "@type": "FAQPage",
  "mainEntity": [
    {
      "@type": "Question",
      "name": "Is the checker free?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "Yes. It is free and needs no account."
      }
    }
  ]
}

Our recommendation is to spend no time on this type. If the FAQ helps readers, put it on the page for them and let the markup follow from the template. If you are choosing between an hour on FAQ markup and an hour on Article and BreadcrumbList correctness, take the second.

What not to mark up

Google’s guideline is that markup has to reflect what is on the page, and the failures follow from it. Do not mark up text that visitors cannot see, such as content hidden with CSS or placed only in the markup. Do not mark up questions that the page does not show. Do not publish an author who does not exist or credentials that nobody holds. Do not add ratings or reviews you do not display, and do not add Product markup to a page that sells nothing. Do not copy a template from another site without replacing every URL and date, because a graph that points at someone else’s pages is worse than none.

Google’s policy describes the penalty as a manual action, which costs the page its eligibility for rich results. Whatever the type, the risk is not worth taking for markup that adds nothing a reader can see.

Generate it from the data that renders the page

The most reliable way to keep markup and page in agreement is to build both from the same source. On this site, a guide’s title, description and publication date come from the frontmatter of the Markdown file, and the template reads those same fields to render the visible heading and to fill headline, description and datePublished. The breadcrumb items come from the same path helpers as the visible breadcrumb trail. Nobody edits the JSON-LD by hand, so it cannot describe an older version of the page.

If your site runs on a CMS, look for the setting or template that outputs the graph, and check what it does when you change a title. If you write static HTML, put the script element in the shared layout and feed it variables. The failure to avoid is the hand-pasted block that was right in January and describes a page that has since been renamed.

Test it before and after you deploy

Paste the page URL or the code into Google’s Rich Results Test. It reports the types it recognizes as eligible and flags missing required properties. Types that are not eligible for a rich result may simply not appear, so the Rich Results Test alone does not prove that every node of your graph is correct.

For that, check two things yourself. First, that the JSON parses: save the block as schema.json and run it through the one-liner below, which prints a message only if the JSON is valid. Second, that the markup arrived in the page you deployed: view the source of the live URL and search for ld+json, since templates sometimes drop the block on one page type. Our SEO checker does both on a live URL: its JSON-LD check fetches the page, parses every block, reports how many are valid or broken, and lists the types it found.

node -e "JSON.parse(require('fs').readFileSync('schema.json','utf8')); console.log('valid JSON')"

Quick answers

Should I remove FAQPage markup I already have?

There is no need to hurry. The markup stays readable by other systems, and as long as the questions and answers are visible on the page and identical to the markup, it does no harm. What we would stop doing is adding it in the hope of a rich result.

Where does the JSON-LD go, in the head or in the body?

Either works. We put one script element in the head, generated from the page template, so the markup always ships with the page it describes.

Do I need a different Article type for a guide?

Article is enough for a guide or a tutorial. More specific types exist, but we use the plain one because the extra precision brings no display we could verify, and a simpler graph is easier to keep correct.

Sources

Who stands behind this

GreenlightMySite is run by Stéphane Cardon, a network and cybersecurity engineer. We write from running real sites through real reviews, and every technical claim here is either linked to a primary source or measured with our own tools.

About · Editorial policy · LinkedIn