# Breadcrumb schema: a JSON‑LD implementation guide

Discover how to implement breadcrumbs in JSON-LD to optimize SEO and improve navigation on your website.

Author: Louis Choquet · Founder, Pharelia

Published on 2026-08-13 · Updated on 2026-08-13

Source: https://pharelia.com/en/resources/fil-dariane-schema

<a id="intro"></a>

## Introduction

![Hands typing on a keyboard in a minimalist workspace dedicated to development and search optimization.](https://pharelia.com/media/6bc41a01598afb804e8d.jpg)

Structured breadcrumbs, or `BreadcrumbList` in the [Schema](https://schema.org/BreadcrumbList) specification, are the markup that lets Google display a readable navigation path in SERPs instead of a raw URL. The minimum implementation requires a `BreadcrumbList` containing several `ListItem` elements, each with `item` (a URL or `@id`) and `position` (an integer starting at 1) properties. The recommended format is JSON‑LD, placed in the page's `<head>`.

Here is a minimal example ready to deploy:

```json <script type="application/ld+json"> { "@context": "https://schema.org", "@type": "BreadcrumbList", "itemListElement": [ { "@type": "ListItem", "position": 1, "name": "Accueil", "item": "https://exemple.fr/" }, { "@type": "ListItem", "position": 2, "name": "Blog", "item": "https://exemple.fr/blog/" }, { "@type": "ListItem", "position": 3, "name": "Mon article", "item": "https://exemple.fr/blog/mon-article/" } ] } </script> ```

> **Remember:** the final `ListItem` can omit the `item` property — Google will then use the current page's URL. Nevertheless, check that this URL matches your canonical.

**Pro tip:** *always test the markup in a staging environment whose canonical URLs are identical to production before deploying. A canonical pointing to staging invalidates the test.*

<a id="points-cles"></a>

## Key takeaways

JSON‑LD `BreadcrumbList` schema, validated through Rich Results Test and aligned with your canonicals, is the most accessible technical way to make your SERP results easier to read.



| Point | Details |
| --- | --- |
| Minimum required structure | A `BreadcrumbList` must contain at least two `ListItem` elements with `name`, `position` (an integer) and `item`. |
| Recommended format | JSON‑LD in the `<head>` — simpler to maintain than microdata or RDFa. |
| Canonical alignment | Every `item` or `@id` must match the represented page's canonical URL exactly. |
| Mandatory validation | Test through Rich Results Test before deployment, then monitor Search Console from D+1. |
| HTML accessibility | Visible breadcrumbs must use `<nav aria-label>` + `<ol>/<li>` + `aria-current="page"`. |
| Pharelia | Pharelia audits structured data, fixes inconsistencies and continuously monitors results. |

<a id="table-des-matieres"></a>

## Table of contents

- [Why breadcrumb schema improves your visibility](#pourquoi-le-schema-fil-dariane-ameliore-votre-visibilite)
- [Which properties are required in a BreadcrumbList?](#quelles-proprietes-sont-obligatoires-dans-un-breadcrumblist)
- [Compliant code examples to deploy](#exemples-de-code-conformes-a-deployer)
- [Where to place the markup and how to align it with your canonical](#ou-placer-le-balisage-et-comment-laligner-avec-votre-canonical)
- [How to test and validate your schema step by step](#comment-tester-et-valider-votre-schema-etape-par-etape)
- [Accessibility and HTML markup for visible breadcrumbs](#accessibilite-et-balisage-html-du-fil-dariane-visible)
- [How to implement breadcrumbs on WordPress](#comment-implementer-le-fil-dariane-sur-wordpress)
- [What are the most common pitfalls to avoid?](#quels-sont-les-pieges-les-plus-courants-a-eviter)
- [What practical experience teaches us about BreadcrumbList](#ce-que-lexperience-terrain-enseigne-sur-le-breadcrumblist)
- [Pharelia audits and fixes your structured data](#pharelia-audite-et-corrige-vos-donnees-structurees)
- [Sources](#sources)
- [Frequently asked questions](#questions-frequentes)

<a id="pourquoi-le-schema-fil-d-ariane-ameliore-votre-visibilite"></a>
<a id="pourquoi-le-schema-fil-dariane-ameliore-votre-visibilite"></a>

## Why breadcrumb schema improves your visibility

`BreadcrumbList` is a structured data type defined jointly by [Google Search Central](https://developers.google.com/search/docs/appearance/structured-data/breadcrumb?hl=fr) and Schema.org. Technically, it is an `ItemList` whose elements are ordered `ListItem` entries representing levels in the website hierarchy.

In SERPs, Google replaces the URL displayed beneath the title with a readable path such as ‘Home › Blog › My article’. This makes the result easier to read and may improve click-through rates, particularly on mobile where long URLs are truncated. Google does not guarantee breadcrumb display even with valid markup, but clean schema significantly increases the chances of obtaining this presentation.

The most relevant use cases:

- E-commerce websites with several category levels (Home › Women › Shoes › Trainers).
- Technical documentation websites or knowledge bases.
- Blogs and publications with sections and subsections.
- Any website with more than two or three navigation levels.

<a id="quelles-proprietes-sont-obligatoires-dans-un-breadcrumblist"></a>

## Which properties are required in a BreadcrumbList?

The Schema.org BreadcrumbList specification and Google's guidelines define a precise set of properties. Here is what you need to know before writing the first line of code.

### Required properties



| Property | Level | Expected type | Role |
| --- | --- | --- | --- |
| `@type` | BreadcrumbList | String | Declares the Schema.org type |
| `itemListElement` | BreadcrumbList | Array of ListItem elements | Contains all path elements |
| `@type` | ListItem | String | Must be `"ListItem"` |
| `position` | ListItem | Integer ≥ 1 | Indicates the order in the path |
| `name` | ListItem | String | Label displayed in SERPs |
| `item` | ListItem | URL or `@id` | Resource URL (required except for the final element) |

### Conventions to follow

According to Schema.org's ListItem specification, `position` must be an integer, never a string such as `"1"` or a decimal value. The recommended order is ascending (`ItemListOrderAscending`), from the most general level to the most specific.

Some additional rules from Google's guidelines:

- Do not include a `ListItem` for the root domain alone (e.g. `https://exemple.fr`) if it does not represent a real navigation level.
- Breadcrumbs must represent a **logical user journey**, not necessarily the raw URL structure.
- Do not mark up non-navigation links: JavaScript anchors, dynamic filters and pagination links do not constitute a navigation path.

**Pro tip:** *use `@id` rather than a simple `item` property when your website already uses Schema.org identifiers for its pages — this strengthens the structured data graph's consistency and makes it easier for Search Console to detect inconsistencies.*

<a id="exemples-de-code-conformes-a-deployer"></a>

## Compliant code examples to deploy

### Complete JSON‑LD with `@id`

```json <script type="application/ld+json"> { "@context": "https://schema.org", "@type": "BreadcrumbList", "itemListElement": [ { "@type": "ListItem", "position": 1, "name": "Accueil", "item": { "@id": "https://exemple.fr/", "name": "Accueil" } }, { "@type": "ListItem", "position": 2, "name": "Catégorie", "item": { "@id": "https://exemple.fr/categorie/", "name": "Catégorie" } }, { "@type": "ListItem", "position": 3, "name": "Page courante" } ] } </script> ```

The third element deliberately omits `item`: Google uses the current page's URL, which Google Search Central confirms is the expected behaviour.

### Microdata: when should you use it?

Microdata and RDFa remain valid alternatives, but maintenance is more demanding because the markup is intertwined with the HTML. A minimal microdata example:

```html <ol itemscope itemtype="https://schema.org/BreadcrumbList"> <li itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem"> <a itemprop="item" href="https://exemple.fr/"> <span itemprop="name">Accueil</span> </a> <meta itemprop="position" content="1" /> </li> <li itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem"> <span itemprop="name">Page courante</span> <meta itemprop="position" content="2" /> </li> </ol> ```

> **Why prefer JSON‑LD?** It goes into the `<head>` without changing HTML rendering, simplifying updates and reducing the risk of introducing visual errors during deployments.

<a id="ou-placer-le-balisage-et-comment-l-aligner-avec-votre-canonical"></a>
<a id="ou-placer-le-balisage-et-comment-laligner-avec-votre-canonical"></a>

## Where to place the markup and how to align it with your canonical

JSON‑LD ideally goes in the `<head>` of each relevant page. If technical constraints (a CMS without direct `<head>` access) require it, placing it immediately before `</body>` remains valid for Google — but `<head>` placement is preferable for code readability and consistency with other structured data.

Canonical alignment is the most commonly neglected point. Every `item` or `@id` in your `BreadcrumbList` must match the represented page's canonical URL exactly. If your product page's canonical is `https://exemple.fr/produit/chaussure-x/`, that URL must appear in the `ListItem`, not a variant with a UTM parameter or a session URL.

Placement best practices:

- Generate JSON‑LD on the server or through a CMS hook to ensure URLs are resolved before rendering.
- Check that the `@id` of the final `ListItem` matches the canonical declared in `<link rel="canonical">`.
- On paginated pages, breadcrumbs must point to the series' canonical page, not the paginated page itself.

**Pro tip:** *on headless architectures (Next.js, Nuxt), inject JSON‑LD through the framework's `<Head>` component to ensure it appears in server rendering (SSR), rather than being added only on the client — crawlers would not execute it reliably.*

<a id="comment-tester-et-valider-votre-schema-etape-par-etape"></a>

## How to test and validate your schema step by step

Validation follows a logical sequence: check JSON syntax, test rich results, then monitor in production.

### Sequential steps

1. **Validate JSON syntax**: paste your block into a JSON validator (jsonlint.com or your IDE extension) to eliminate missing commas and unclosed quotation marks before any other test.
2. **Test with Rich Results Test**: Google's tool ([Search](https://search.google.com/test/rich-results)) analyses a URL or pasted code and reports whether `BreadcrumbList` is detected and valid, detailing errors and warnings.
3. **Inspect the URL in Search Console**: after deployment, use Google Search Console's URL Inspection tool to check that Googlebot sees the markup and no `position` errors are reported.
4. **Monitor the Structured Data report**: Search Console's ‘Structured Data’ report lists errors detected across the website. Configure an alert or check it after every major deployment.

Specific points to watch:

- A non-integer `position` value (e.g. the string `"1"` or `1.0`) produces a warning in Rich Results Test.
- Inconsistent URLs between `item` and the actual canonicals trigger Search Console errors.
- Test in staging with the same canonical URLs as production — otherwise the test validates a different context from the one that will be indexed.

**Pro tip:** *integrate Rich Results Test into your CI/CD pipeline through the Google Search Console API or a tool such as Screaming Frog configured to audit structured data on every scheduled crawl. This detects regressions before they reach production.*

<a id="accessibilite-et-balisage-html-du-fil-d-ariane-visible"></a>
<a id="accessibilite-et-balisage-html-du-fil-dariane-visible"></a>

## Accessibility and HTML markup for visible breadcrumbs

JSON‑LD schema is invisible to the user. Breadcrumbs displayed on screen must meet WCAG accessibility standards independently of the structured markup.

The [French government design system](https://www.systeme-de-design.gouv.fr/version-courante/fr/composants/fil-d-ariane/code-du-fil-d-ariane) provides a reference model for accessible HTML code, applicable to any French web project subject to digital accessibility requirements (RGAA). The recommended structure:

```html <nav role="navigation" aria-label="Vous êtes ici :"> <ol> <li> <a href="https://exemple.fr/">Accueil</a> </li> <li> <a href="https://exemple.fr/categorie/">Catégorie</a> </li> <li aria-current="page"> Page courante </li> </ol> </nav> ```

> **Official reference:** the government design system recommends `<nav>` with an explicit `aria-label` and an ordered `<ol>` list so assistive technologies correctly convey the navigation's order and nature.

Accessibility checklist to validate before going live:

- `aria-current="page"` on the final element (the current page, not clickable).
- Visual separators (‘›’ or ‘/’) implemented in CSS (`::after`), not HTML, to prevent screen readers reading them aloud.
- Working keyboard navigation: every link reachable with Tab and a visible focus indicator.
- Sufficient contrast between breadcrumb links and the background (ratio ≥ 4,5:1 for normal text).

<a id="comment-implementer-le-fil-d-ariane-sur-wordpress"></a>
<a id="comment-implementer-le-fil-dariane-sur-wordpress"></a>

## How to implement breadcrumbs on WordPress

### Through an SEO plugin (recommended approach)

[SEOPress](https://www.seopress.org/fr/fonctionnalites/fil-dariane/) automatically generates HTML breadcrumbs and provides a dedicated JSON‑LD option for crawlers, with control over separators and path templates. Activate it under Appearance › SEOPress › Breadcrumbs, then enable ‘Enable JSON‑LD breadcrumbs’. Other plugins such as Breadcrumb NavXT ([available on WordPress.org](https://fr.wordpress.org/plugins/breadcrumb-navxt/)) offer similar customization options.

![A workspace equipped with SEO tools and a notebook for taking notes](https://pharelia.com/media/0d7e7d968a8cba933b54.jpg)

For websites with multiple categories, SEOPress lets you define a primary term for each article, preventing inconsistent paths between pages of the same content type.

### PHP injection through the `wp_head` hook

If you prefer controlling JSON‑LD without depending on a plugin, add this hook to `functions.php`:

```php add_action( 'wp_head', 'mon_breadcrumb_jsonld' ); function mon_breadcrumb_jsonld() { if ( ! is_singular() ) return; $items = [];

// Exemple minimal pour une page de catégorie : $items[] = [ 'position' => 1, 'name' => 'Accueil', 'item' => home_url('/') ]; $items[] = [ 'position' => 2, 'name' => get_the_title(), 'item' => get_permalink() ]; $schema = [ '@context'        => 'https://schema.org', '@type'           => 'BreadcrumbList', 'itemListElement' => array_map( function($i) { return [ '@type' => 'ListItem' ] + $i; }, $items ), ]; echo '<script type="application/ld+json">' . wp_json_encode($schema) . '</script>'; } ```

**Pro tip:** *after activating a plugin or deploying the PHP hook, always clear the cache (caching plugin + CDN), then immediately test a representative URL with Rich Results Test. Cache errors are the main cause of undetected markup after deployment.*

WordPress post-activation checklist:

- Cache cleared (WP Rocket, W3 Total Cache, Cloudflare).
- Canonical checked on a test page (Search Console inspection tool).
- Rich Results Test passed on at least three page types (homepage, category, article).
- Primary term configured for articles in multiple categories.

<a id="quels-sont-les-pieges-les-plus-courants-a-eviter"></a>

## What are the most common pitfalls to avoid?

Most production `BreadcrumbList` errors fall into four categories.

**Non-integer positions.** A `"1"` value (string) instead of `1` (integer) produces a warning in Rich Results Test. Check that your JSON serializer does not surround integers with quotation marks.

**URLs inconsistent with canonicals.** If `item` points to `https://exemple.fr/produit/?ref=newsletter` while the canonical is `https://exemple.fr/produit/`, Search Console detects an inconsistency. Always use the clean canonical URL.

**Marking up non-navigation links.** A search filter, JavaScript anchor link or pagination link is not a navigation level. `BreadcrumbList` must represent a path a user can actually follow by clicking.

**A path that does not reflect actual navigation.** Marking up the raw URL structure rather than the logical user journey is a common mistake. If your URL is `/fr/blog/2024/categorie/article/`, the breadcrumbs do not necessarily need all these segments — only those corresponding to real navigation pages.

Pre-deployment checklist:

- All `position` values are integers.
- Every `item` matches a valid, accessible canonical URL (HTTP 200).
- JSON‑LD is syntactically valid (jsonlint.com).
- Rich Results Test reports no errors (warnings are acceptable but must be documented).
- Visible HTML markup follows the `nav/ol/li` structure with `aria-current`.
- Search Console monitoring is configured for structured data.

**Pro tip:** *for multilingual websites, generate a distinct `BreadcrumbList` for each language version, with URLs matching each language's hreflang canonicals. Do not share one schema across several versions.*

<a id="ce-que-l-experience-terrain-enseigne-sur-le-breadcrumblist"></a>
<a id="ce-que-lexperience-terrain-enseigne-sur-le-breadcrumblist"></a>

## What practical experience teaches us about BreadcrumbList

Structured breadcrumbs are often treated as an end-of-sprint task, added afterwards. This is a prioritisation mistake. On e-commerce and documentation websites we audit at Pharelia, missing or incorrectly configured `BreadcrumbList` is among the most frequently absent structured data, although it is one of the simplest to implement correctly.

What strikes me more is the persistent confusion between visible HTML breadcrumbs and JSON‑LD schema. Some developers implement one without the other, or both inconsistently — different URLs in the structured markup and HTML links. Google reconciles both signals: an inconsistency between them can reduce confidence in the schema.

The process we consistently recommend: a technical audit of existing structured data, staging implementation with canonical URLs identical to production, automated Rich Results Test validation, then gradual deployment with Search Console monitoring active from D+1. Automating `BreadcrumbList` audits in the CI/CD pipeline reduces regressions during template updates — a point teams underestimate until their first post-deployment incident.

![What practical experience teaches us about BreadcrumbList — overview diagram](https://pharelia.com/media/7585c77b6aa5deb26707.jpg)

<a id="pharelia-audite-et-corrige-vos-donnees-structurees"></a>

## Pharelia audits and fixes your structured data

[![Pharelia](https://pharelia.com/media/bc90afef6a57451e8c81.png)](https://pharelia.com/en/contact)

An incorrectly configured `BreadcrumbList` generates no visible error — it goes unnoticed until the next Search Console audit. Pharelia handles the full technical scope: auditing existing structured data, fixing canonical/`@id` inconsistencies, validating through Rich Results Test and continuously monitoring Search Console. We deploy into your current stack — WordPress, Shopify, Webflow or any custom architecture — without reconfiguring your environment.

Every engagement starts with a free visibility audit covering crawling, structured data and organic performance signals. For teams wanting to go further with visibility in generative engines, our AI search optimization resources complement the technical work.

[Contact us](/en/contact).

<a id="sources"></a>

## Sources

Official resources and validation tools for exploring and maintaining your implementation:

- [Breadcrumb structured data (BreadcrumbList) — Google Search Central](https://developers.google.com/search/docs/appearance/structured-data/breadcrumb?hl=fr)
- [Schema](https://schema.org/BreadcrumbList)
- [Breadcrumb code — French government design system](https://www.systeme-de-design.gouv.fr/version-courante/fr/composants/fil-d-ariane/code-du-fil-d-ariane)
- [WordPress breadcrumbs - SEOPress](https://www.seopress.org/fr/fonctionnalites/fil-dariane/)

<a id="questions-frequentes"></a>

## Frequently asked questions

### What are breadcrumbs in computing?

Breadcrumbs are a navigation element showing users their position in a website's hierarchy as a clickable path (e.g. Home › Category › Page). In SEO, the term also refers to `BreadcrumbList` markup, which communicates this hierarchy to Google as structured data.

### What is the difference between HTML breadcrumbs and JSON‑LD schema?

HTML breadcrumbs are the visible on-screen component users navigate. JSON‑LD schema is an invisible metadata block placed in the `<head>`, communicating the same hierarchy to Google for SERP display. The two must be consistent.

### Do structured breadcrumbs guarantee display in Google?

No. Google explicitly states that valid `BreadcrumbList` markup increases the chances of a navigation path appearing in results, but does not guarantee it. Other factors matter, including overall page quality and relevance signals.

### How many `ListItem` elements are needed in a BreadcrumbList?

A minimum number of elements is required under Google Search Central's guidelines to form a valid navigation path.

### How should you manage breadcrumbs on a WordPress website with multiple categories?

Define a documented priority rule for each article's primary term, and configure your plugin (SEOPress, for example) to use that primary term consistently in the path. Apply the rule uniformly to avoid inconsistent paths between pages of the same content type.

<a id="recommandation"></a>

## Recommendation

- SEO, GEO and AEO services | Pharelia
- [Structured data in 2026: what Google actually expects | Pharelia](https://pharelia.com/en/resources/donnees-structurees-schema)
- [Semantic content clusters in 2026: building them for SEO and AI | Pharelia](https://pharelia.com/en/resources/cocon-semantique)
