How to add breadcrumb schema (BreadcrumbList JSON-LD)
Add breadcrumb schema with BreadcrumbList JSON-LD: required ListItem properties, visible HTML vs JSON-LD, numbered steps, common mistakes, and validation before publish.
To add breadcrumb schema, publish a visible breadcrumb trail on the page and mirror it with one BreadcrumbList JSON-LD block in the head. Each step is a ListItem with a position and name; every step before the current page needs an absolute URL that matches the link visitors click. JSON-LD is the usual format for developer-led sites. Validate the live URL before you treat the page as done.
Breadcrumb schema is not a substitute for internal links or sitemaps. It tells search engines how this URL sits in your hierarchy when the visible trail and the markup agree. When they disagree, rich results may drop the breadcrumb and reviewers may flag the page under structured data policies.
What BreadcrumbList Schema Does
BreadcrumbList is the schema.org type for a ordered path from a broad page to the page being viewed. Google documents it under breadcrumb structured data. The type does not create navigation by itself. It describes navigation that already exists.
When markup matches the visible trail, search results may show that path above the title. That can clarify where a URL lives in a large site. The benefit is clarity for crawlers and searchers, not a guaranteed ranking lift.
One page should carry one BreadcrumbList. Nested products, filtered views, and alternate URLs each need a trail that reflects what a visitor actually sees on that URL, including the canonical URL you want indexed.
Required Properties for BreadcrumbList
At minimum, a valid BreadcrumbList includes @context, @type, and itemListElement. Each element in that array is a ListItem with these fields:
| Property | Role | Notes |
|---|---|---|
@type on each item |
Must be ListItem |
Do not reuse WebPage inside the list. |
position |
1-based order | Start at 1 for home or the top hub; increment by one with no gaps. |
name |
Visible label | Should match the anchor text or current-page label on the page. |
item |
URL of the step | Use absolute URLs for every step except the current page unless your template intentionally repeats the canonical URL on the last item. |
A minimal three-step example:
{
"@context": "https://schema.org",
"@type": "BreadcrumbList",
"itemListElement": [
{
"@type": "ListItem",
"position": 1,
"name": "Home",
"item": "https://example.com/"
},
{
"@type": "ListItem",
"position": 2,
"name": "Docs",
"item": "https://example.com/docs"
},
{
"@type": "ListItem",
"position": 3,
"name": "API reference"
}
]
}
Place the block in the document head inside <script type="application/ld+json">. Escape any </script> sequences inside the JSON if your templating language injects raw strings.
Visible HTML Breadcrumbs vs JSON-LD
Visitors see HTML, usually a list of links in a nav with an accessible name. Crawlers read that HTML plus any JSON-LD you add. The two representations should tell the same story.
A typical visible pattern:
<nav aria-label="Breadcrumb">
<ol>
<li><a href="/">Home</a></li>
<li><a href="/docs">Docs</a></li>
<li aria-current="page">API reference</li>
</ol>
</nav>
JSON-LD carries the same names and URLs in machine-readable form. You do not need microdata on every anchor if JSON-LD is complete and accurate. Some CMS plugins emit microdata instead; that is fine when it stays in sync with the visible trail.
Choose one source of truth in your codebase. Many Laravel or Next.js apps build an array of crumbs in the layout, render the HTML from it, and serialize the same array into JSON-LD. That pattern prevents the classic failure mode where marketing edits the visible trail but engineering forgets the script block.
For broader JSON-LD patterns on SaaS sites, see the schema section of SEO for developers. This article stays focused on breadcrumbs only so it does not compete with the schema markup generator tool pages.
Steps to Add Breadcrumb Schema
Work in this order so you do not validate markup that does not match the page.
- Confirm the visible trail. Walk the URL in a browser. Every step except the current page should be a normal link with descriptive text. If the trail is JavaScript-only, fix HTML first.
- Pick canonical URLs for each step. Use the same host, scheme, and path form you use in
link rel="canonical". Avoid tracking parameters in breadcrumb links. - Build the ListItem array in code. Map position from array index plus one. Copy
namefrom the visible label. Setitemto the absolute URL for each link step. - Emit one JSON-LD script in the head. Serialize the array with
@contextand@type": "BreadcrumbList". Keep pretty-printing out of production if byte size matters; minified JSON is valid. - Ship through your usual review path. Treat schema like any template change: pull request, snapshot or unit test on the serialized output, and a reviewer who compares names to the design.
- Validate the published URL. Run the live page through the Schema Markup Validator or Google's Rich Results Test. Fix template data when a property is missing, not only the JSON you pasted by hand during development.
If you prefer to draft JSON-LD before wiring the template, use the free breadcrumb schema generator to prototype ListItems, then move the same values into your layout component. The generator is a scratchpad; the implementation still lives in your repo.
Common Breadcrumb Schema Mistakes
| Mistake | Why it fails | Fix |
|---|---|---|
| Markup without a visible trail | Violates structured data guidance on visible content | Add HTML breadcrumbs or remove the JSON-LD |
| Names or URLs that differ from the page | Rich results require alignment with on-page links | Single source of truth array for HTML and JSON-LD |
Skipped position values |
Breaks ordered list semantics | Renumber from 1 with no gaps |
| Relative URLs in JSON-LD | Validators and crawlers expect absolute item values |
Prefix with your site origin in the serializer |
| Two BreadcrumbList blocks | Conflicting graphs on one URL | Merge into one list or remove duplicates from plugins |
| Breadcrumbs on the homepage | A single-step list adds little and clutters templates | Omit BreadcrumbList on the root URL unless design requires it |
Another frequent issue is copying a competitor's trail structure without matching your URL architecture. Breadcrumbs should reflect your site, not a generic "Products > Category > Item" template when your URLs use /collections/ or flat slugs.
Validate Breadcrumb Schema
Validation is a production check, not a local-only step. Staging URLs behind login, different hosts, or draft content will not prove the live graph is correct.
- Schema syntax: Confirm JSON parses and required properties exist on every ListItem.
- Visible parity: Compare each
nameand linkeditemto the rendered breadcrumb in desktop and mobile layouts. - Indexability: The page must not be blocked by robots.txt or
noindexif you expect enhanced results. - One graph: View page source and search for
BreadcrumbList. Resolve duplicate blocks from SEO plugins or tag managers.
After a template change, spot-check a hub page, a deep article, and a paginated or filtered URL if your app generates different trails per route. Automated tests can assert that your layout outputs the expected number of ListItems for a fixture route.
More free checks live on Orchory's SEO tools hub, including the schema markup generator for other types when this page's BreadcrumbList work is done.
When breadcrumb schema is one item in a larger technical SEO queue, Orchory helps teams rank page opportunities and ship fixes as reviewed pull requests. Request access to connect research to the implementation workflow, or prototype ListItems now with the breadcrumb schema generator.