Structured Data for Content Platforms: A Practical JSON-LD Guide

1 min read
Cover image for Untitled Paper

Most of what Google knows about your pages comes from reading your HTML headings, paragraphs, links. But HTML is ambiguous. A page with a name, a photo, and a list of articles could be a blog, a portfolio, a news outlet, or a social profile. Google has to guess.

Structured data removes the guessing. It's a block of machine-readable information you add to your page that says explicitly: "This is a Person. Their name is this. They've authored these Articles. This is their ProfilePage." Google reads it, understands your content more precisely, and can display richer search results as a result.

For a content platform with multiple page types profiles, projects, papers structured data is one of the highest-leverage technical SEO investments you can make.


What Structured Data Actually Does

Structured data can do two things depending on what you implement:

Help Google understand your content better. Even if your content never qualifies for a rich result, structured data improves how Google categorizes and understands your pages. This affects ranking, not just appearance.

Unlock rich results in search. For certain schema types, Google displays enhanced search results: star ratings, article dates and authors, breadcrumb trails, FAQs. These increase CTR (click-through rate) significantly compared to standard results.

The most common format for structured data is JSON-LD (JavaScript Object Notation for Linked Data). It lives in a <script type="application/ld+json"> tag in your page's <head>. It doesn't affect how the page looks it's purely for machines.


The Schema Types You Need for a Content Platform

Different page types need different schema. Here's the mapping for a platform like Whitepaper:

PageSchema Types
HomepageOrganization, WebSite
User profile pagePerson, ProfilePage
Project pageCollectionPage
Individual paper pageArticle, BreadcrumbList
Blog postBlogPosting, BreadcrumbList

You don't need all of these on day one. Start with Article on your blog posts and Person on profile pages these have the clearest ranking benefits and are easiest to validate.


Homepage: Organization + WebSite

Your homepage should tell Google who you are as an entity:

{
  "@context": "https://schema.org",
  "@type": "Organization",
  "name": "Whitepaper",
  "url": "https://whitepaper.so",
  "logo": "https://whitepaper.so/logo.png",
  "description": "API-first CMS platform for developer publishing with built-in SEO and content distribution.",
  "sameAs": [
    "https://twitter.com/whitepaper",
    "https://github.com/whitepaper"
  ]
}

Add a WebSite block too, which enables the Sitelinks Search Box in Google (the search bar that appears within your Google search result):

{
  "@context": "https://schema.org",
  "@type": "WebSite",
  "name": "Whitepaper",
  "url": "https://whitepaper.so",
  "potentialAction": {
    "@type": "SearchAction",
    "target": {
      "@type": "EntryPoint",
      "urlTemplate": "https://whitepaper.so/search?q={search_term_string}"
    },
    "query-input": "required name=search_term_string"
  }
}

Both of these go on the homepage only. You can put them in one <script> tag using the @graph format, or two separate tags both are valid.


User Profile Pages: Person + ProfilePage

When someone visits a user's profile on your platform, they're viewing a Person's published work. The schema reflects this:

{
  "@context": "https://schema.org",
  "@graph": [
    {
      "@type": "Person",
      "@id": "https://whitepaper.so/devjohn#person",
      "name": "John Dev",
      "url": "https://whitepaper.so/devjohn",
      "image": "https://whitepaper.so/avatars/devjohn.jpg",
      "description": "Developer and technical writer. Writing about APIs, DevOps, and open source."
    },
    {
      "@type": "ProfilePage",
      "@id": "https://whitepaper.so/devjohn#profilepage",
      "url": "https://whitepaper.so/devjohn",
      "name": "John Dev's Profile",
      "about": { "@id": "https://whitepaper.so/devjohn#person" },
      "mainEntity": { "@id": "https://whitepaper.so/devjohn#person" }
    }
  ]
}

Generate this dynamically from your user profile API response. The @id field creates a link between the Person and ProfilePage entities this is important for Google's entity understanding.


Paper Pages: Article + BreadcrumbList

Individual papers are articles. This is the schema type with the most direct impact on search results Google can display the author name, publish date, and a breadcrumb trail in the search result.

{
  "@context": "https://schema.org",
  "@graph": [
    {
      "@type": "Article",
      "headline": "How to Design an API-First CMS",
      "description": "A practical guide to building a CMS that separates content from presentation using a headless API architecture.",
      "image": "https://whitepaper.so/thumbnails/api-first-cms.jpg",
      "datePublished": "2026-01-15",
      "dateModified": "2026-03-10",
      "author": {
        "@type": "Person",
        "name": "John Dev",
        "url": "https://whitepaper.so/devjohn"
      },
      "publisher": {
        "@type": "Organization",
        "name": "Whitepaper",
        "logo": {
          "@type": "ImageObject",
          "url": "https://whitepaper.so/logo.png"
        }
      },
      "mainEntityOfPage": {
        "@type": "WebPage",
        "@id": "https://whitepaper.so/devjohn/api-first-cms"
      }
    },
    {
      "@type": "BreadcrumbList",
      "itemListElement": [
        {
          "@type": "ListItem",
          "position": 1,
          "name": "Home",
          "item": "https://whitepaper.so"
        },
        {
          "@type": "ListItem",
          "position": 2,
          "name": "John Dev",
          "item": "https://whitepaper.so/devjohn"
        },
        {
          "@type": "ListItem",
          "position": 3,
          "name": "How to Design an API-First CMS",
          "item": "https://whitepaper.so/devjohn/api-first-cms"
        }
      ]
    }
  ]
}

All fields here come directly from your content API headline from title, datePublished from publishedAt, dateModified from updatedAt, author fields from the user object. Build a function that takes a paper object and returns this schema, and call it from your paper page template.


Project Pages: CollectionPage

A project that groups multiple papers is a CollectionPage in schema terms:

{
  "@context": "https://schema.org",
  "@type": "CollectionPage",
  "name": "API Design Patterns",
  "description": "A collection of papers on REST, GraphQL, and event-driven API design.",
  "url": "https://whitepaper.so/devjohn/p/api-design-patterns",
  "author": {
    "@type": "Person",
    "name": "John Dev",
    "url": "https://whitepaper.so/devjohn"
  },
  "hasPart": [
    {
      "@type": "Article",
      "name": "REST vs GraphQL",
      "url": "https://whitepaper.so/devjohn/rest-vs-graphql"
    },
    {
      "@type": "Article",
      "name": "Designing Webhook Payloads",
      "url": "https://whitepaper.so/devjohn/webhook-payload-design"
    }
  ]
}

The hasPart array establishes a relationship between the project and its papers. This helps Google understand that these articles belong to a collection, which can improve how it treats the cluster of pages.


Validating Your Structured Data

Always validate before deploying. Bugs in JSON-LD a missing comma, an unclosed brace cause the entire block to be silently ignored.

Google's Rich Results Test (search.google.com/test/rich-results): Paste a URL or raw HTML and see exactly what schema Google detected and whether it's valid. This is your primary validation tool.

Schema Markup Validator (validator.schema.org): Checks schema validity against the official schema.org specification. More strict than Google's tool, which is useful for catching subtle issues.

Search Console Enhancement reports: After your pages are indexed, Search Console shows enhancement reports for each schema type (Articles, Breadcrumbs, etc.) with any errors or warnings at scale.


Common Mistakes

Putting structured data in a client-rendered component. If your JSON-LD is injected by JavaScript after page load, Google may not see it consistently. Always render structured data server-side in the <head>.

Using the same schema on every page. Your homepage schema and article schema should be completely different. Don't copy-paste Article schema onto your pricing page.

Leaving fields blank. An Article with no datePublished or no author is less useful than one that's complete. Pull real data for every field or omit the field entirely if data isn't available.

Mismatching schema content with visible content. If your Article schema says the author is "John Dev" but the page displays a different name, Google may flag it as a mismatch.


Starting Small

You don't need to implement all of this at once. A practical starting order:

  1. Organization + WebSite on homepage (30 minutes)
  2. Article + BreadcrumbList on paper pages (template work, applies to all papers automatically)
  3. Person + ProfilePage on user profile pages
  4. CollectionPage on project pages
  5. BlogPosting on marketing blog posts

Each one builds on a working template, applies automatically to all pages of that type, and can be validated independently before moving to the next.


Part of our series on Programmatic SEO and Content Operations. Start with the complete pillar guide or read about crawl budget management.

Whitepapper

Whitepapper is an API first CMS engine for devs who publish content.

Antk i n