← Back to Documentation
    DocumentationintegrationsFeb 11, 2025

    Schema.org Structured Data Reference

    Complete reference for Schema.org structured data markup: JSON-LD examples for every major schema type, rich results eligibility, testing tools, and implementation patterns for static sites, Next.js, React, and WordPress.

    What Structured Data Does

    Structured data is machine-readable markup that tells search engines, voice assistants, and AI systems exactly what your page content means. Instead of relying on algorithms to infer meaning from raw HTML, you declare it explicitly using a shared vocabulary defined at schema.org.

    Search engine benefits:

    • Rich results — star ratings, prices, FAQ accordions, recipe cards, how-to steps, and event listings displayed directly in Google Search results
    • Knowledge panels — branded panels on the right side of search results for organizations, people, and products
    • Voice search / Google Assistant — structured data powers direct answers in voice queries (e.g., "What are the hours for [business]?")
    • AI citations — large language models and AI search engines (Google AI Overviews, Bing Copilot, Perplexity) use structured data to surface and attribute information

    Measurable impact:

    • Pages with rich results earn significantly higher click-through rates than plain blue links
    • FAQ rich results can double your SERP real estate
    • Product rich results with price and availability reduce bounce rates from unqualified clicks
    • BreadcrumbList markup replaces raw URLs in search results with readable navigation paths

    Formats: JSON-LD, Microdata, RDFa

    Three formats exist for embedding structured data in HTML. Google explicitly recommends JSON-LD.

    JSON-LD (Recommended)

    JavaScript Object Notation for Linked Data. Placed in a <script> tag in the document <head> or <body>. Completely decoupled from the visual HTML — you never mix markup with display code.

    <script type="application/ld+json">
    {
      "@context": "https://schema.org",
      "@type": "Organization",
      "name": "Example Corp"
    }
    </script>
    

    Why Google prefers JSON-LD:

    • No coupling between markup and presentation — easier to maintain
    • Can be injected dynamically by JavaScript frameworks
    • Simpler to validate and debug
    • No risk of breaking page layout when modifying structured data
    • Supports nesting and complex graphs cleanly

    Microdata

    Inline HTML attributes (itemscope, itemtype, itemprop) mixed directly into page elements.

    <div itemscope itemtype="https://schema.org/Organization">
      <span itemprop="name">Example Corp</span>
    </div>
    

    When to use: Legacy systems where you cannot add <script> tags, or when structured data must mirror visible content exactly (rare).

    RDFa

    Similar to Microdata — uses vocab, typeof, and property attributes inline.

    <div vocab="https://schema.org/" typeof="Organization">
      <span property="name">Example Corp</span>
    </div>
    

    When to use: Rarely. RDFa is more common in non-HTML contexts (XML, SVG). For web pages, JSON-LD covers every use case.

    Bottom line: Use JSON-LD for all new implementations. It is the only format that cleanly separates data from presentation.

    Schema Types and JSON-LD Examples

    Organization

    Defines a company or organization. Powers knowledge panels and branded search features.

    {
      "@context": "https://schema.org",
      "@type": "Organization",
      "name": "Cogny AI",
      "url": "https://cogny.com",
      "logo": "https://cogny.com/images/logo.png",
      "sameAs": [
        "https://twitter.com/cognyai",
        "https://linkedin.com/company/cogny",
        "https://github.com/cognyai"
      ],
      "contactPoint": {
        "@type": "ContactPoint",
        "telephone": "+46-8-123-4567",
        "contactType": "customer service",
        "availableLanguage": ["English", "Swedish"]
      },
      "foundingDate": "2023",
      "numberOfEmployees": {
        "@type": "QuantitativeValue",
        "value": 15
      }
    }
    

    Required: name Recommended: url, logo, sameAs, contactPoint Rich result: Knowledge panel (right sidebar in Google Search)

    LocalBusiness

    Extends Organization for businesses with a physical location. Powers local pack results and Google Maps.

    {
      "@context": "https://schema.org",
      "@type": "LocalBusiness",
      "name": "Nordic Coffee Roasters",
      "image": "https://example.com/photos/storefront.jpg",
      "url": "https://nordiccoffee.se",
      "telephone": "+46-8-765-4321",
      "priceRange": "$$",
      "address": {
        "@type": "PostalAddress",
        "streetAddress": "Drottninggatan 45",
        "addressLocality": "Stockholm",
        "addressRegion": "Stockholm",
        "postalCode": "111 21",
        "addressCountry": "SE"
      },
      "geo": {
        "@type": "GeoCoordinates",
        "latitude": 59.3293,
        "longitude": 18.0686
      },
      "openingHoursSpecification": [
        {
          "@type": "OpeningHoursSpecification",
          "dayOfWeek": ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday"],
          "opens": "07:00",
          "closes": "18:00"
        },
        {
          "@type": "OpeningHoursSpecification",
          "dayOfWeek": ["Saturday", "Sunday"],
          "opens": "09:00",
          "closes": "16:00"
        }
      ],
      "sameAs": [
        "https://instagram.com/nordiccoffee",
        "https://facebook.com/nordiccoffee"
      ]
    }
    

    Required: name, address Recommended: geo, openingHoursSpecification, telephone, priceRange, image Rich result: Local pack, knowledge panel with map, hours, and phone

    Product

    Defines a product with pricing and availability. Powers product rich results in Google Search and Shopping.

    {
      "@context": "https://schema.org",
      "@type": "Product",
      "name": "Wireless Noise-Cancelling Headphones",
      "image": [
        "https://example.com/photos/headphones-front.jpg",
        "https://example.com/photos/headphones-side.jpg"
      ],
      "description": "Premium wireless headphones with active noise cancellation, 30-hour battery life, and multipoint Bluetooth connectivity.",
      "sku": "WH-1000XM5",
      "brand": {
        "@type": "Brand",
        "name": "AudioTech"
      },
      "offers": {
        "@type": "Offer",
        "url": "https://example.com/headphones-wh1000xm5",
        "priceCurrency": "USD",
        "price": "349.99",
        "priceValidUntil": "2025-12-31",
        "availability": "https://schema.org/InStock",
        "itemCondition": "https://schema.org/NewCondition",
        "seller": {
          "@type": "Organization",
          "name": "AudioTech Store"
        }
      },
      "aggregateRating": {
        "@type": "AggregateRating",
        "ratingValue": "4.7",
        "bestRating": "5",
        "reviewCount": "2847"
      }
    }
    

    Required for rich results: name, image, offers (with price, priceCurrency, availability) Recommended: sku, brand, aggregateRating, description Rich result: Product snippet with price, availability, and star rating

    FAQPage

    Defines a page containing frequently asked questions. Powers FAQ accordion rich results.

    {
      "@context": "https://schema.org",
      "@type": "FAQPage",
      "mainEntity": [
        {
          "@type": "Question",
          "name": "What is structured data?",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "Structured data is machine-readable markup added to HTML pages that helps search engines understand your content. It uses the Schema.org vocabulary and is typically implemented in JSON-LD format."
          }
        },
        {
          "@type": "Question",
          "name": "Does structured data improve SEO rankings?",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "Structured data does not directly affect rankings. However, it enables rich results that significantly improve click-through rates, which can indirectly improve performance through higher engagement signals."
          }
        },
        {
          "@type": "Question",
          "name": "How many FAQs should I include per page?",
          "acceptedAnswer": {
            "@type": "Answer",
            "text": "Google will display up to 10 FAQ results per page. Focus on quality over quantity — include the most relevant questions that match real user search intent."
          }
        }
      ]
    }
    

    Required: mainEntity array with Question items, each containing acceptedAnswer Rich result: Expandable FAQ accordion directly in search results (up to 10 questions)

    HowTo

    Defines step-by-step instructions. Powers how-to rich results with numbered steps and images.

    {
      "@context": "https://schema.org",
      "@type": "HowTo",
      "name": "How to Implement JSON-LD Structured Data",
      "description": "A step-by-step guide to adding Schema.org JSON-LD structured data to your website.",
      "totalTime": "PT15M",
      "estimatedCost": {
        "@type": "MonetaryAmount",
        "currency": "USD",
        "value": "0"
      },
      "tool": [
        {
          "@type": "HowToTool",
          "name": "Text editor or CMS"
        },
        {
          "@type": "HowToTool",
          "name": "Google Rich Results Test"
        }
      ],
      "step": [
        {
          "@type": "HowToStep",
          "name": "Choose your schema type",
          "text": "Identify the primary content type of your page (Product, Article, FAQPage, etc.) and look up the required and recommended properties at schema.org.",
          "url": "https://example.com/guide#step1",
          "image": "https://example.com/images/step1-choose-type.png"
        },
        {
          "@type": "HowToStep",
          "name": "Write the JSON-LD block",
          "text": "Create a JSON-LD script block with @context set to https://schema.org, @type set to your chosen type, and all required properties filled in with accurate data from your page.",
          "url": "https://example.com/guide#step2",
          "image": "https://example.com/images/step2-write-jsonld.png"
        },
        {
          "@type": "HowToStep",
          "name": "Insert into your page",
          "text": "Place the script tag in the head or body of your HTML document. For JavaScript frameworks, use the appropriate head management library.",
          "url": "https://example.com/guide#step3",
          "image": "https://example.com/images/step3-insert.png"
        },
        {
          "@type": "HowToStep",
          "name": "Validate with testing tools",
          "text": "Run your page through the Google Rich Results Test and the Schema Markup Validator to confirm the markup is error-free and eligible for rich results.",
          "url": "https://example.com/guide#step4",
          "image": "https://example.com/images/step4-validate.png"
        }
      ]
    }
    

    Required: name, step (with text for each step) Recommended: image per step, totalTime, tool, supply Rich result: Numbered step-by-step instructions with optional images

    Article / BlogPosting

    Defines news articles, blog posts, and other editorial content. Powers article rich results with headline, author, and thumbnail.

    {
      "@context": "https://schema.org",
      "@type": "BlogPosting",
      "headline": "Complete Guide to Schema.org Structured Data",
      "description": "Learn how to implement structured data markup to earn rich results in Google Search.",
      "image": [
        "https://example.com/images/structured-data-guide-16x9.jpg",
        "https://example.com/images/structured-data-guide-4x3.jpg",
        "https://example.com/images/structured-data-guide-1x1.jpg"
      ],
      "author": {
        "@type": "Person",
        "name": "Anna Lindqvist",
        "url": "https://example.com/authors/anna-lindqvist"
      },
      "publisher": {
        "@type": "Organization",
        "name": "Example Publishing",
        "logo": {
          "@type": "ImageObject",
          "url": "https://example.com/logo.png"
        }
      },
      "datePublished": "2025-01-15",
      "dateModified": "2025-02-10",
      "mainEntityOfPage": {
        "@type": "WebPage",
        "@id": "https://example.com/guides/structured-data"
      }
    }
    

    Use @type: "Article" for news, "BlogPosting" for blog content, "NewsArticle" for news publishers in Google News.

    Required for rich results: headline, image, datePublished, author Recommended: dateModified, publisher, description, mainEntityOfPage Rich result: Article carousel, Top Stories (NewsArticle), author and date in search results

    BreadcrumbList

    Defines the navigation path to a page. Replaces raw URLs in search results with readable breadcrumb trails.

    {
      "@context": "https://schema.org",
      "@type": "BreadcrumbList",
      "itemListElement": [
        {
          "@type": "ListItem",
          "position": 1,
          "name": "Home",
          "item": "https://example.com/"
        },
        {
          "@type": "ListItem",
          "position": 2,
          "name": "Documentation",
          "item": "https://example.com/docs"
        },
        {
          "@type": "ListItem",
          "position": 3,
          "name": "Structured Data Reference",
          "item": "https://example.com/docs/structured-data-reference"
        }
      ]
    }
    

    Required: itemListElement with position, name, and item (URL) for each level Rich result: Breadcrumb trail replaces the URL in search results (e.g., "Example > Documentation > Structured Data")

    Review / AggregateRating

    Defines individual reviews or aggregated ratings for a product, service, or business.

    {
      "@context": "https://schema.org",
      "@type": "Product",
      "name": "Cloud Analytics Platform",
      "review": [
        {
          "@type": "Review",
          "reviewRating": {
            "@type": "Rating",
            "ratingValue": "5",
            "bestRating": "5"
          },
          "author": {
            "@type": "Person",
            "name": "Erik Johansson"
          },
          "reviewBody": "Transformed our data pipeline. The BigQuery integration is seamless and the AI insights save us hours every week.",
          "datePublished": "2025-01-20"
        }
      ],
      "aggregateRating": {
        "@type": "AggregateRating",
        "ratingValue": "4.8",
        "bestRating": "5",
        "ratingCount": "312",
        "reviewCount": "189"
      }
    }
    

    Reviews must be nested inside the item they review (Product, LocalBusiness, etc.) — standalone Review markup without an itemReviewed context will not generate rich results.

    Required: ratingValue, bestRating, author (for Review); ratingValue, ratingCount (for AggregateRating) Rich result: Star rating snippet in search results

    Event

    Defines events with dates, location, and ticket information. Powers event rich results and event packs.

    {
      "@context": "https://schema.org",
      "@type": "Event",
      "name": "Nordic Growth Marketing Summit 2025",
      "description": "Two-day conference on performance marketing, AI-driven analytics, and growth strategies for Nordic businesses.",
      "startDate": "2025-09-15T09:00:00+02:00",
      "endDate": "2025-09-16T17:00:00+02:00",
      "eventStatus": "https://schema.org/EventScheduled",
      "eventAttendanceMode": "https://schema.org/OfflineEventAttendanceMode",
      "location": {
        "@type": "Place",
        "name": "Stockholm Waterfront Congress Centre",
        "address": {
          "@type": "PostalAddress",
          "streetAddress": "Nils Ericsons Plan 4",
          "addressLocality": "Stockholm",
          "postalCode": "111 64",
          "addressCountry": "SE"
        }
      },
      "performer": {
        "@type": "Organization",
        "name": "Cogny AI"
      },
      "offers": {
        "@type": "Offer",
        "url": "https://example.com/tickets",
        "price": "4999",
        "priceCurrency": "SEK",
        "availability": "https://schema.org/InStock",
        "validFrom": "2025-03-01T00:00:00+01:00"
      },
      "organizer": {
        "@type": "Organization",
        "name": "Growth Hackers Stockholm",
        "url": "https://growthhackers.se"
      },
      "image": "https://example.com/images/summit-2025.jpg"
    }
    

    Required: name, startDate, location Recommended: endDate, offers, performer, eventStatus, eventAttendanceMode, image Rich result: Event listing with date, location, and ticket link; event pack in search results

    VideoObject

    Defines a video with metadata for video rich results and Google Video search.

    {
      "@context": "https://schema.org",
      "@type": "VideoObject",
      "name": "How to Set Up GA4 BigQuery Export",
      "description": "Step-by-step tutorial for connecting Google Analytics 4 to BigQuery, configuring the export, and verifying data flow.",
      "thumbnailUrl": "https://example.com/thumbnails/ga4-bigquery-setup.jpg",
      "uploadDate": "2025-01-10",
      "duration": "PT12M30S",
      "contentUrl": "https://example.com/videos/ga4-bigquery-setup.mp4",
      "embedUrl": "https://youtube.com/embed/abc123",
      "interactionStatistic": {
        "@type": "InteractionCounter",
        "interactionType": {
          "@type": "WatchAction"
        },
        "userInteractionCount": 15420
      }
    }
    

    Required: name, thumbnailUrl, uploadDate Recommended: description, duration, contentUrl or embedUrl Rich result: Video carousel, video thumbnail in search results, Google Video search listing

    SoftwareApplication

    Defines a software product with platform and pricing information.

    {
      "@context": "https://schema.org",
      "@type": "SoftwareApplication",
      "name": "Cogny Analytics Platform",
      "operatingSystem": "Web",
      "applicationCategory": "BusinessApplication",
      "description": "AI-powered analytics platform that connects to BigQuery, Google Ads, and Meta Ads for automated growth insights.",
      "offers": {
        "@type": "Offer",
        "price": "99",
        "priceCurrency": "USD"
      },
      "aggregateRating": {
        "@type": "AggregateRating",
        "ratingValue": "4.8",
        "ratingCount": "156"
      },
      "screenshot": "https://example.com/images/dashboard-screenshot.png"
    }
    

    Required: name, offers (with price and priceCurrency) Recommended: operatingSystem, applicationCategory, aggregateRating Rich result: Software snippet with rating and price

    Course

    Defines an educational course with provider information.

    {
      "@context": "https://schema.org",
      "@type": "Course",
      "name": "Advanced BigQuery for Marketing Analytics",
      "description": "Learn to write efficient BigQuery SQL for GA4 data, build marketing attribution models, and create automated reporting pipelines.",
      "provider": {
        "@type": "Organization",
        "name": "Cogny Academy",
        "sameAs": "https://cogny.com/academy"
      },
      "courseCode": "BQ-301",
      "hasCourseInstance": {
        "@type": "CourseInstance",
        "courseMode": "online",
        "courseSchedule": {
          "@type": "Schedule",
          "repeatFrequency": "P1W",
          "startDate": "2025-03-01",
          "endDate": "2025-04-15"
        }
      },
      "offers": {
        "@type": "Offer",
        "price": "499",
        "priceCurrency": "USD",
        "category": "Paid"
      }
    }
    

    Required: name, description, provider Recommended: offers, hasCourseInstance, courseCode Rich result: Course listing with provider and enrollment information

    JobPosting

    Defines a job listing with compensation, location, and requirements.

    {
      "@context": "https://schema.org",
      "@type": "JobPosting",
      "title": "Senior Growth Engineer",
      "description": "We are looking for a senior growth engineer to build and optimize our marketing analytics infrastructure, including BigQuery pipelines, A/B testing frameworks, and automated reporting.",
      "datePosted": "2025-02-01",
      "validThrough": "2025-04-01T23:59:59+01:00",
      "employmentType": "FULL_TIME",
      "hiringOrganization": {
        "@type": "Organization",
        "name": "Cogny AI",
        "sameAs": "https://cogny.com",
        "logo": "https://cogny.com/images/logo.png"
      },
      "jobLocation": {
        "@type": "Place",
        "address": {
          "@type": "PostalAddress",
          "addressLocality": "Stockholm",
          "addressRegion": "Stockholm",
          "addressCountry": "SE"
        }
      },
      "jobLocationType": "TELECOMMUTE",
      "baseSalary": {
        "@type": "MonetaryAmount",
        "currency": "SEK",
        "value": {
          "@type": "QuantitativeValue",
          "minValue": 55000,
          "maxValue": 75000,
          "unitText": "MONTH"
        }
      },
      "applicantLocationRequirements": {
        "@type": "Country",
        "name": "Sweden"
      }
    }
    

    Required: title, description, datePosted, hiringOrganization, jobLocation Recommended: validThrough, employmentType, baseSalary, jobLocationType Rich result: Job listing in Google Jobs with salary, location, and apply button

    Testing and Validation

    Google Rich Results Test

    URL: search.google.com/test/rich-results

    Test individual pages or code snippets for rich result eligibility. Shows which rich result types are detected, whether they pass validation, and lists any errors or warnings.

    Use for: Pre-launch validation, debugging specific pages, testing JSON-LD snippets before deployment.

    Schema Markup Validator

    URL: validator.schema.org

    Validates against the full Schema.org specification (not just Google's subset). Catches structural errors, incorrect types, and missing required properties that the Rich Results Test might not flag.

    Use for: Spec compliance, catching edge cases, validating schema types that Google does not currently use for rich results.

    Google Search Console Rich Results Report

    Location: Search Console > Enhancements > [specific rich result type]

    Shows aggregate data across your entire site: how many pages have valid structured data, how many have errors, and which specific errors are most common. Updated daily.

    Use for: Ongoing monitoring, catching regressions after deployments, tracking rich result coverage over time.

    Common Validation Errors and Fixes

    ErrorCauseFix
    Missing field "image"Product or Article missing required imageAdd image property with a valid URL to a crawlable image
    Invalid URL in field "url"Relative URL instead of absoluteUse fully qualified URLs (e.g., https://example.com/page)
    Missing field "author"Article or Review missing authorAdd author as a Person or Organization object with name
    Invalid value in field "price"Price includes currency symbolUse numeric value only (e.g., "349.99" not "$349.99")
    Invalid enum value for "availability"Plain text instead of Schema.org URLUse https://schema.org/InStock, not "In Stock"
    Warning: missing recommended fieldRecommended property omittedNot blocking, but add it for best rich result presentation
    Array expected, single value foundSingle image instead of arrayWrap in array: "image": ["https://..."]
    datePublished is in the futurePublish date set ahead of actual publishSet datePublished to the actual publication date

    Best Practices

    One Primary Schema Type per Page

    Each page should have one primary schema type that matches its main content purpose. A product page uses Product schema, a blog post uses Article or BlogPosting, a FAQ page uses FAQPage. You can combine complementary types (e.g., BreadcrumbList alongside the primary type), but do not add multiple competing primary types.

    Nesting vs. Flat Structures

    Nest when there is a clear parent-child relationship:

    {
      "@type": "Product",
      "name": "Widget",
      "offers": {
        "@type": "Offer",
        "price": "29.99"
      }
    }
    

    Use @graph for multiple independent entities on the same page:

    {
      "@context": "https://schema.org",
      "@graph": [
        {
          "@type": "BreadcrumbList",
          "itemListElement": [...]
        },
        {
          "@type": "Product",
          "name": "Widget",
          "offers": {...}
        }
      ]
    }
    

    Required vs. Recommended Properties

    Google documents required and recommended properties for each rich result type. Required properties must be present for the rich result to appear at all. Recommended properties improve the quality and appearance of the rich result. Always include both.

    Reference: developers.google.com/search/docs/appearance/structured-data/search-gallery

    Avoiding Spammy Markup

    Google penalizes structured data that misrepresents page content:

    • Fake reviews: Do not fabricate reviews or ratings. AggregateRating must reflect real user reviews
    • Misleading content: Schema properties must match visible page content. If your Product schema says the price is $29.99, that price must be visible on the page
    • Hidden markup: Do not add structured data for content that is not visible to users
    • Schema type mismatch: Do not mark a category page as a Product, or a marketing page as an Article
    • Self-serving reviews: Do not add Review markup where the reviewed item is the page owner's own product without genuine third-party reviews

    Google's manual actions for structured data spam can remove all rich results from your entire site.

    Keeping Schema in Sync with Page Content

    Structured data must always reflect the current, visible page content. Stale markup (outdated prices, discontinued products still marked InStock, old dates) triggers validation warnings and can result in manual actions.

    Recommendations:

    • Generate structured data dynamically from the same data source as the page content
    • Include schema updates in your CMS publishing workflow
    • Set up Search Console alerts for structured data errors
    • Audit structured data quarterly or after major site changes

    Rich Results Eligibility

    Which schema types trigger which rich results in Google Search:

    Schema TypeRich ResultSERP Appearance
    ProductProduct snippetPrice, availability, rating stars below listing
    FAQPageFAQ accordionExpandable Q&A directly in results
    HowToHow-to stepsNumbered steps with optional images
    Article / BlogPostingArticle resultAuthor, date, thumbnail image
    NewsArticleTop StoriesCarousel at top of results
    BreadcrumbListBreadcrumb trailReplaces URL with navigation path
    Review / AggregateRatingReview snippetStar rating below listing
    EventEvent listingDate, location, ticket info in event pack
    VideoObjectVideo resultThumbnail, duration in video carousel
    LocalBusinessLocal packMap pin, hours, phone, directions
    JobPostingGoogle JobsSalary, location, apply button in jobs widget
    SoftwareApplicationSoftware resultRating, price
    CourseCourse listingProvider, schedule, enrollment
    RecipeRecipe cardCook time, calories, rating, image
    OrganizationKnowledge panelLogo, social links, description (right sidebar)

    Not all schema types generate rich results. Google supports a specific subset — check the Search Gallery for the current list.

    Implementation Patterns

    Static HTML Injection

    Add the JSON-LD <script> tag directly in your HTML <head>:

    <!DOCTYPE html>
    <html>
    <head>
      <title>Product Page</title>
      <script type="application/ld+json">
      {
        "@context": "https://schema.org",
        "@type": "Product",
        "name": "Widget Pro",
        "offers": {
          "@type": "Offer",
          "price": "49.99",
          "priceCurrency": "USD",
          "availability": "https://schema.org/InStock"
        }
      }
      </script>
    </head>
    <body>...</body>
    </html>
    

    Best for simple static sites, landing pages, and server-rendered pages.

    Next.js / React Head Management

    Use Next.js <Script> component or the metadata API:

    // app/products/[slug]/page.tsx (App Router)
    export default function ProductPage({ product }) {
      const jsonLd = {
        "@context": "https://schema.org",
        "@type": "Product",
        name: product.name,
        image: product.images,
        description: product.description,
        sku: product.sku,
        brand: {
          "@type": "Brand",
          name: product.brand,
        },
        offers: {
          "@type": "Offer",
          priceCurrency: product.currency,
          price: product.price,
          availability: product.inStock
            ? "https://schema.org/InStock"
            : "https://schema.org/OutOfStock",
        },
      };
    
      return (
        <>
          <script
            type="application/ld+json"
            dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
          />
          {/* Page content */}
        </>
      );
    }
    

    For the Pages Router, use next/head:

    import Head from "next/head";
    
    export default function ProductPage({ product }) {
      const jsonLd = { /* ... same as above ... */ };
    
      return (
        <>
          <Head>
            <script
              type="application/ld+json"
              dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }}
            />
          </Head>
          {/* Page content */}
        </>
      );
    }
    

    WordPress Plugins

    For WordPress sites, several plugins handle structured data without manual coding:

    • Yoast SEO — Automatically generates Organization, Article, BreadcrumbList, and other schema types. Includes a schema tab for per-page customization
    • Rank Math — Built-in schema generator with a visual editor. Supports 20+ schema types with per-post configuration
    • Schema Pro — Dedicated structured data plugin with conditional rules (e.g., add Product schema to all pages in the "Shop" category)

    Manual approach in WordPress — Add JSON-LD via the wp_head action:

    add_action('wp_head', function() {
        if (is_singular('product')) {
            $product = get_post();
            $price = get_post_meta($product->ID, '_price', true);
            $schema = [
                '@context' => 'https://schema.org',
                '@type' => 'Product',
                'name' => $product->post_title,
                'description' => $product->post_excerpt,
                'offers' => [
                    '@type' => 'Offer',
                    'price' => $price,
                    'priceCurrency' => 'USD',
                    'availability' => 'https://schema.org/InStock',
                ],
            ];
            echo '<script type="application/ld+json">' . json_encode($schema) . '</script>';
        }
    });
    

    Dynamic Generation from CMS Data

    For headless CMS setups (Contentful, Sanity, Strapi), generate structured data from the API response:

    // Generic pattern for any CMS
    function generateProductSchema(cmsData: CMSProduct): object {
      return {
        "@context": "https://schema.org",
        "@type": "Product",
        name: cmsData.title,
        image: cmsData.media.map((m) => m.url),
        description: cmsData.shortDescription,
        sku: cmsData.sku,
        brand: {
          "@type": "Brand",
          name: cmsData.brand.name,
        },
        offers: {
          "@type": "Offer",
          price: cmsData.variants[0].price.toString(),
          priceCurrency: cmsData.currency,
          availability: cmsData.inStock
            ? "https://schema.org/InStock"
            : "https://schema.org/OutOfStock",
        },
      };
    }
    

    The key principle: structured data should be generated from the same data source that populates the page, never hardcoded separately. This ensures schema stays in sync with visible content.

    Claude Code Skill

    This structured data reference is also available as a free Claude Code skill — use it directly in your terminal:

    # Install
    curl -sSL https://raw.githubusercontent.com/cognyai/claude-code-marketing-skills/main/install.sh | bash
    
    # Use
    /structured-data                          # Full reference overview
    /structured-data Product                  # Show Product schema example
    /structured-data FAQPage                  # Show FAQPage example
    /structured-data validate                 # Testing and validation guide
    

    View on GitHub →

    Resources

    Ready for similar results?
    Start with Solo at $9/mo or talk to us about Cloud.
    ❯ get startedcompare plans →