JSON-LD Schema Markup: Comprehensive SEO Implementation Guide

Last Update 28/03/2026
Structured data Rich results

JSON-LD structured data informs search engines precisely about your content. Proper schema markup enables rich results in Google Search — including FAQ dropdowns, article carousels, breadcrumb trails, and more — shown directly in search listings.

This guide details all key schema types with authentic C# code and exact JSON output, using examples from a live Blazor codebase.

Diagram illustrating JSON-LD structured data generating rich results in Google Search, such as FAQ dropdowns, article carousels, and breadcrumb navigation
JSON-LD structured data is the easiest to maintain for schema markup — it resides in a script tag, fully separate from your HTML.

What JSON-LD is and its importance for SEO

JSON-LD (JavaScript Object Notation for Linked Data) encodes structured data in JSON format. Search engines like Google use this to grasp your content’s meaning beyond keywords.

When Google interprets your structured data, your pages qualify for rich results — enhanced listings showing ratings, FAQ dropdowns, images, breadcrumbs, and more directly in search results. These typically attract more clicks than standard links.

Google advises using JSON-LD rather than Microdata or RDFa, as it can be placed anywhere on the page, including the head, without altering existing HTML. This keeps structured data separate from your markup.

Eligibility for rich results

Correct schema markup qualifies your pages for FAQ dropdowns, article carousels, breadcrumb trails, and other rich features in Google Search.

Increased clicks without ranking change

Clear semantic meaning

Structured data removes uncertainty. A page with Q&A content is marked as a FAQPage, so Google displays it as a FAQ rich result.

Inform search engines precisely about your content

No changes to HTML required

JSON-LD is placed in a script tag within the head, separate from visible HTML, so adding or updating schema won’t disrupt layouts or accessibility.

Clear separation of concerns

JSON-LD compared to Microdata and RDFa

There are three ways to embed schema.org structured data in web pages. Google recognises all, but they vary greatly in application and upkeep.

Format Syntax location Maintenance SEO impact Google’s recommendation
JSON-LD Separate script tag Simple — no HTML edits Complete rich result compatibility Recommended
Microdata Inline HTML attributes High — closely tied to markup Complete rich result compatibility Supported
RDFa Inline HTML attributes High — closely tied to markup Complete rich result compatibility Supported

Why JSON-LD is easier to maintain

Microdata and RDFa scatter schema attributes across your HTML. Template changes can break structured data unnoticed. JSON-LD is self-contained — updating the script won’t affect HTML.

Top choice for web development learning

Master contemporary web development with SEO essentials

A tip from me I found this course useful for grasping how technical SEO, structured data, and modern web standards combine in practical projects.

  • Discover how to implement HTML meta tags, Open Graph, and JSON-LD structured data.
  • Effective SEO techniques to improve search engine visibility and rankings.
  • Practical projects focusing on responsive design and optimising performance.
Explore the web development course

Key schema types and their uses

Schema.org lists hundreds of types, but a few cover most web content. These types enable rich results in Google Search.

Schema type Use case Type of rich result
Article Blog posts, guides, news articles Article carousel, Top stories
FAQPage Pages featuring question and answer pairs FAQ dropdown in search results
BreadcrumbList Pages with navigation hierarchy Breadcrumb trail beneath the URL
WebSite / WebPage Homepage, hub pages, landing pages Sitelinks search box, entity recognition
SoftwareApplication Apps, tools, software products App rich result showing rating and price

Schema.org vocabulary

All schema types are defined at schema.org. The @context property in each JSON-LD block instructs parsers to interpret properties using the schema.org vocabulary. Multiple schema types can be combined on one page — Google processes each script separately.

Implementing Article schema

Article schema is vital for content sites. It informs Google of the headline, description, publication date, author, and publisher — the essential properties for rich result eligibility.

The C# class below models serialization. Each property maps directly to the corresponding JSON-LD field via JsonPropertyName attributes.

C#ArticleSchema C# class (JsonLdService.cs)
private class ArticleSchema
{
    [JsonPropertyName("@context")]
    public string Context { get; } = "https://schema.org";

    [JsonPropertyName("@type")]
    public string Type { get; } = "Article";

    [JsonPropertyName("headline")]
    public string? Headline { get; set; }

    [JsonPropertyName("description")]
    public string? Description { get; set; }

    [JsonPropertyName("image")]
    public string? Image { get; set; }

    [JsonPropertyName("url")]
    public string? Url { get; set; }

    [JsonPropertyName("author")]
    public Organization? Author { get; set; }

    [JsonPropertyName("publisher")]
    public ArticlePublisher? Publisher { get; set; }

    [JsonPropertyName("datePublished")]
    public string? DatePublished { get; set; }

    [JsonPropertyName("dateModified")]
    public string? DateModified { get; set; }

    [JsonPropertyName("articleSection")]
    public List<string>? ArticleSection { get; set; }
}

Required properties include headline, image, datePublished, dateModified, author, and publisher. The articleSection array is optional but advised — it indicates the article’s topical focus to Google.

HTMLArticle schema JSON-LD output
<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "Article",
  "headline": "JSON-LD Schema Markup: Complete SEO Implementation Guide",
  "description": "Learn how to implement JSON-LD structured data for Article, FAQPage, BreadcrumbList, WebSite, and WebPage schema types.",
  "image": "https://ghostlyinc.com/images/web/jsonldguide/opengraph/hero-1200.png",
  "url": "https://ghostlyinc.com/en/json-ld-schema-markup-seo-guide/",
  "author": {
    "@type": "Organization",
    "name": "GhostlyInc",
    "url": "https://ghostlyinc.com"
  },
  "publisher": {
    "@type": "Organization",
    "name": "GhostlyInc",
    "logo": {
      "@type": "ImageObject",
      "url": "https://ghostlyinc.com/images/logo.png"
    }
  },
  "datePublished": "2026-03-28T10:00:00Z",
  "dateModified": "2026-03-28T10:00:00Z",
  "articleSection": [
    "What is JSON-LD and why it matters for SEO",
    "JSON-LD vs. Microdata vs. RDFa",
    "Core schema types and when to use them",
    "Article schema implementation"
  ]
}
</script>

Both author and publisher are typed as Organization. For personal blogs, the author may be a Person with a name and URL.

FAQ schema for rich snippets

FAQPage schema generates FAQ rich results — expandable Q&A pairs shown directly in Google Search below your listing. This can greatly increase vertical space, boosting visibility and click-through rates.

The FaqPage class contains a list of question entities. Each must have a name (the question) and an acceptedAnswer with a text property (the answer).

C#FaqPage C# class (JsonLdService.cs)
private class FaqPage
{
    [JsonPropertyName("@context")]
    public string Context { get; } = "https://schema.org";

    [JsonPropertyName("@type")]
    public string Type { get; } = "FAQPage";

    [JsonPropertyName("@id")]
    public string? Id { get; set; }

    [JsonPropertyName("name")]
    public string? Name { get; set; }

    [JsonPropertyName("mainEntity")]
    public List<FaqEntity>? MainEntity { get; set; }
}

private class FaqEntity
{
    [JsonPropertyName("@type")]
    public string Type { get; } = "Question";

    [JsonPropertyName("name")]
    public string? Name { get; set; }

    [JsonPropertyName("acceptedAnswer")]
    public FaqAnswer? AcceptedAnswer { get; set; }
}

private class FaqAnswer
{
    [JsonPropertyName("@type")]
    public string Type { get; } = "Answer";

    [JsonPropertyName("text")]
    public string? Text { get; set; }
}

The output is a single FAQPage block with a mainEntity array. Each item is a Question type with an acceptedAnswer. Google supports up to ten questions per page for rich results.

HTMLFAQ schema JSON-LD output
<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "FAQPage",
  "@id": "https://ghostlyinc.com/en/json-ld-schema-markup-seo-guide/#faq",
  "name": "Frequently asked questions",
  "mainEntity": [
    {
      "@type": "Question",
      "name": "What is the difference between JSON-LD and Microdata?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "JSON-LD is a separate script block that lives in the head and does not touch HTML. Microdata adds attributes directly to HTML elements. Google recommends JSON-LD for its maintainability."
      }
    },
    {
      "@type": "Question",
      "name": "How many FAQ questions can I mark up?",
      "acceptedAnswer": {
        "@type": "Answer",
        "text": "Google supports up to ten questions per page for the FAQ rich result. Additional questions are still valid schema but will not appear in the search result enhancement."
      }
    }
  ]
}
</script>

The @id on the FAQPage block anchors the schema to a specific URL fragment. This best practice helps parsers clearly identify each entity on pages with multiple schema blocks.

WebSite and WebPage schema

WebSite and WebPage schema form the core entity graph for a site. WebSite identifies the site — its name, URL, language, and publisher. WebPage describes the page and links it to the WebSite via isPartOf.

Both classes use the same JSON-LD pattern. The @id on WebSite is the domain root; on WebPage it is the full page URL.

C#WebSiteSchema and WebPageSchema C# classes (JsonLdService.cs)
private class WebSiteSchema
{
    [JsonPropertyName("@context")]
    public string Context { get; } = "https://schema.org";

    [JsonPropertyName("@type")]
    public string Type { get; } = "WebSite";

    [JsonPropertyName("name")]
    public string? Name { get; set; }

    [JsonPropertyName("url")]
    public string? Url { get; set; }

    [JsonPropertyName("inLanguage")]
    public string? InLanguage { get; set; }

    [JsonPropertyName("publisher")]
    public Organization? Publisher { get; set; }
}

private class WebPageSchema
{
    [JsonPropertyName("@context")]
    public string Context { get; } = "https://schema.org";

    [JsonPropertyName("@type")]
    public string Type { get; } = "WebPage";

    [JsonPropertyName("@id")]
    public string? Id { get; set; }

    [JsonPropertyName("name")]
    public string? Name { get; set; }

    [JsonPropertyName("description")]
    public string? Description { get; set; }

    [JsonPropertyName("url")]
    public string? Url { get; set; }

    [JsonPropertyName("inLanguage")]
    public string? InLanguage { get; set; }

    [JsonPropertyName("isPartOf")]
    public WebSiteReference? IsPartOf { get; set; }
}

The inLanguage property uses BCP 47 codes (e.g. en, de, fr). The isPartOf link connects the WebPage to the WebSite entity by referencing the domain’s @id, aiding Google in building a full entity model.

HTMLWebSite and WebPage schema JSON-LD output
<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "WebSite",
  "name": "GhostlyInc",
  "url": "https://ghostlyinc.com",
  "inLanguage": "en",
  "publisher": {
    "@type": "Organization",
    "name": "GhostlyInc",
    "url": "https://ghostlyinc.com"
  }
}
</script>

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "WebPage",
  "@id": "https://ghostlyinc.com/en/json-ld-schema-markup-seo-guide/",
  "name": "JSON-LD Schema Markup: Complete SEO Implementation Guide",
  "description": "Learn how to implement JSON-LD structured data for Article, FAQPage, BreadcrumbList, WebSite, and WebPage schema types.",
  "url": "https://ghostlyinc.com/en/json-ld-schema-markup-seo-guide/",
  "inLanguage": "en",
  "isPartOf": {
    "@type": "WebSite",
    "@id": "https://ghostlyinc.com"
  }
}
</script>

Best practices for implementation

The WrapInScriptTag helper method converts JSON strings into valid JSON-LD blocks by wrapping them in a script tag with the application/ld+json MIME type.

All schema builders — Article, FAQPage, BreadcrumbList, WebSite, and WebPage — use this method to pass their serialized JSON to the utility.

C#WrapInScriptTag method (JsonLdService.cs)
private static MarkupString WrapInScriptTag(string json)
{
    var builder = new StringBuilder();
    builder.AppendLine("<script type=\"application/ld+json\">");
    builder.AppendLine(json);
    builder.AppendLine("</script>");

    return new MarkupString(builder.ToString());
}

The SchemaContext object is the entry point for BuildSchema. It holds all data needed to build schema blocks for a page — type, metadata, FAQs, breadcrumbs, and article info.

C#BuildSchema dispatch logic (JsonLdService.cs)
public SchemaBuildResult BuildSchema(SchemaContext context)
{
    if (context == null) throw new ArgumentNullException(nameof(context));

    var jsonLd = new List<MarkupString>();

    switch (context.PageType)
    {
        case PageSchemaType.Home:
            jsonLd.Add(WebSite(context));
            jsonLd.Add(WebPage(context));
            break;
        case PageSchemaType.Article:
            jsonLd.Add(Article(context.Article!));
            break;
        case PageSchemaType.Tool:
            jsonLd.Add(WebPage(context));
            jsonLd.Add(SoftwareApplication(context.SoftwareApplication!));
            break;
        case PageSchemaType.Hub:
            jsonLd.Add(WebPage(context));
            break;
    }

    if (context.Faqs != null && context.Faqs.Count > 0)
    {
        jsonLd.Add(FAQ(context.Faqs.ToList(), context.FaqTitle, context.Url));
    }

    if (context.ParentHierarchy.Count > 0)
    {
        jsonLd.Add(BreadcrumbList(BuildBreadcrumbItems(context)));
    }

    return new SchemaBuildResult(jsonLd, context.PageType == PageSchemaType.Article);
}

The dispatch switch allows composable schema building. FAQs and breadcrumbs are appended if present, regardless of page type, enabling any page to include these without altering core logic.

Testing and validating your schema

Valid JSON-LD syntax alone doesn’t guarantee rich results. Google’s tools verify syntax and whether your content meets policies for each rich result type.

Rich Results Test

Use search.google.com/test/rich-results to test URLs or raw HTML. Google shows detected rich result types and flags missing required properties.

Google’s official eligibility checker

Schema Markup Validator

validator.schema.org validates your markup against schema.org specs independently of Google’s rich result policies. Useful for spotting typos and type errors.

Schema.org syntax validation

Google Search Console

The Enhancements section in Search Console reports schema errors and warnings across your indexed pages. Use it for ongoing monitoring after initial checks.

Monitor at scale after launch

Frequently asked questions

Answers to common JSON-LD schema markup questions