BreadcrumbList schema: positions, names and what breaks
Breadcrumb markup with no itemListElement, items missing position or name, or positions out of order. squirrel checks every non-homepage URL.
What BreadcrumbList schema is
BreadcrumbList is the schema.org type for the trail of pages that leads to the current one. It holds an itemListElement array of ListItem nodes, each with a position starting at 1, a name, and an item URL. The last entry is the current page and does not need an item.
It describes a path, not the navigation widget, so the markup should mirror the trail a reader would follow rather than the site’s whole menu. A homepage has no trail, which is why this rule skips it.
What squirrel checks
The rule reads every script[type="application/ld+json"] on the page and keeps the first BreadcrumbList node from the last script that contains one, matching either a plain @type or an @type array. It emits one or more checks:
breadcrumb-schema: on the homepage, meaning a URL path of/or empty, it reports at info status with the messageHomepage - breadcrumbs not typically neededand stops. On any other page with noBreadcrumbListnode it reports at info status with the messageNo BreadcrumbList schema foundand the valueConsider adding for non-homepage.breadcrumb-items: warns with the messageBreadcrumbList has no itemswhenitemListElementis absent, is not an array, or is empty. It warns with the messageSome breadcrumb items missing position or namewhen at least one entry lacks either property.breadcrumb-order: warns with the messageBreadcrumb positions not sequentialwhen a numericpositionis not one more than the previous entry’s. The first entry is compared against 1, so a list starting at 0 or 2 is reported. This check is pushed once per offending entry, so a badly numbered list emits it more than once.breadcrumb-valid: passes with the messageBreadcrumbList has N item(s)when every entry has both apositionand aname.
The sequence check only runs on positions that are JavaScript numbers. A position written as the string "1" is accepted as present by breadcrumb-valid but skipped by breadcrumb-order, so a string-numbered list never reports as out of order. Every property test is a truthiness test rather than a presence test, so a property present but empty, 0 or false counts as missing. A position of 0 and a name of "" therefore both read as missing.
An itemListElement entry that is a node reference, {"@id": "…#crumb-1"}, is read from the ListItem node with that @id anywhere in the page’s JSON-LD, in the same @graph or another script. A relative @id resolves against the page URL. A reference to a node the page does not have counts as an item missing its position and name.
How to fix it
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "BreadcrumbList",
"itemListElement": [
{ "@type": "ListItem", "position": 1, "name": "Guides", "item": "https://example.com/guides" },
{ "@type": "ListItem", "position": 2, "name": "Deployment" }
]
}
</script>Put it in the <head> of the page it describes, number the positions from 1 with no gaps, and emit them as numbers rather than strings.
JSON-LD wrapped in an @graph array, which is what Yoast, Rank Math and several other generators emit, is read the same as a top-level node: the rule flattens each script before looking for BreadcrumbList.
| Rule ID | schema/breadcrumb |
| Category | Structured Data |
| Scope | Per-page |
| Severity | info |
| Weight | 3/10 |
Enable / disable
Disable this rule
[rules]
disable = ["schema/breadcrumb"]Disable all Structured Data rules
[rules]
disable = ["schema/*"]Enable only this rule
[rules]
enable = ["schema/breadcrumb"]enable replaces the default ["*"], so this is the only rule selected. Leave disable out: a rule that matches any disable pattern is skipped even when enable names it. Only an enabled setting under a rule’s own [rule_options] table overrides both lists.
Related rules
- schema/json-ld-valid: whether the JSON-LD parses and passes schema.org validation at all.
- links/internal-links: how many internal links a page carries, which the trail is part of.
- url/slug-convention: URLs that break the site’s own path conventions, which the trail usually mirrors.
- schema/coverage-outlier: pages missing markup the rest of their page type carries.
Structured data findings ship in every audit next to the core SEO, performance and agent experience rules. See Fix SEO issues with AI for how an agent works through a report.
References
Check your site
Run squirrel audit https://example.com and open the Structured Data section of the report. Each page shows how many breadcrumb items it declared. Signed-out local audits need no account and cost nothing. Signed-in audits spend credits.