/ โ† Internal Link Fixes / Add breadcrumb navigation
In this guide
  1. What breadcrumb functionality does
  2. Types of breadcrumbs and which to use
  3. Accessible breadcrumb HTML
  4. Matching BreadcrumbList schema
  5. Adding breadcrumbs in WordPress, Shopify and custom sites
  6. A worked example
  7. The fix, step by step
  8. Edge cases worth knowing
  9. Keeping breadcrumbs accurate
  10. Questions and answers

What breadcrumb functionality does

A breadcrumb trail is a secondary navigation aid. It shows the path from the home page to the current page and turns each step, except the last, into a link:

Home  /  Cakes  /  Birthday cakes  /  Chocolate fudge cake

It does three jobs at once:

Breadcrumbs supplement your main menu; they never replace it. They suit sites with more than two levels: shops, documentation, blogs with categories and service businesses with several locations or services. A one-page site or a flat site with five pages gains little from them.

Types of breadcrumbs and which to use

TypeShowsExampleUse it?
Location (hierarchy)Where the page sits in the site structureHome / Cakes / Birthday cakesYes, this is the standard choice
AttributeFilters or properties of a productHome / Cakes / Gluten free / Under ยฃ30Sometimes, on shops with faceted filters
Path (history)The pages this visitor clicked throughChanges per visitNo; the browser back button already does this

Use location breadcrumbs that reflect one stable hierarchy. If a product sits in two categories, choose one primary category and use it in the trail every time, so the trail and the markup do not change from visit to visit.

๐Ÿ’ก Breadcrumbs work best when your URLs and categories already follow a clear structure. If your categories are muddled, sort those first; the trail only reflects what is there.

Accessible breadcrumb HTML

The pattern recommended in the W3C's ARIA Authoring Practices is a nav landmark containing an ordered list:

<nav aria-label="Breadcrumb">
  <ol>
    <li><a href="https://example.com/">Home</a></li>
    <li><a href="https://example.com/cakes/">Cakes</a></li>
    <li><a href="https://example.com/cakes/birthday/">Birthday cakes</a></li>
    <li><a href="https://example.com/cakes/birthday/chocolate-fudge/" aria-current="page">Chocolate fudge cake</a></li>
  </ol>
</nav>

Why each part is there:

Add the separators with CSS, not as characters in the HTML, so screen readers do not read out a string of slashes:

nav[aria-label="Breadcrumb"] ol { display: flex; flex-wrap: wrap; list-style: none; padding: 0; margin: 0; }
nav[aria-label="Breadcrumb"] li + li::before { content: "/"; margin: 0 0.5em; }
nav[aria-label="Breadcrumb"] [aria-current="page"] { font-weight: 600; text-decoration: none; }

Place the trail above the main heading, after the site header and any skip to content link. Use flex-wrap so long trails wrap on phones rather than overflowing the screen.

Matching BreadcrumbList schema

The visible trail and the structured data should describe the same path. Add a JSON-LD block like this to the same page:

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "BreadcrumbList",
  "itemListElement": [
    { "@type": "ListItem", "position": 1, "name": "Home", "item": "https://example.com/" },
    { "@type": "ListItem", "position": 2, "name": "Cakes", "item": "https://example.com/cakes/" },
    { "@type": "ListItem", "position": 3, "name": "Birthday cakes", "item": "https://example.com/cakes/birthday/" },
    { "@type": "ListItem", "position": 4, "name": "Chocolate fudge cake" }
  ]
}
</script>

Google shows breadcrumb paths in desktop search results; since early 2025, mobile results show the site name and domain rather than the trail. The markup is still read on both and remains a clear statement of your site structure. For the format itself see what JSON-LD is, and for common Search Console messages see breadcrumb structured data issues.

โš ๏ธ Do not mark up a trail that is not on the page, and do not make the markup deeper or different from the visible breadcrumbs. Structured data must reflect what visitors can see.

Adding breadcrumbs in WordPress, Shopify and custom sites

WordPress

Many themes include breadcrumbs in their customiser settings. If yours does not, an SEO plugin can output both the trail and the schema:

<?php
if ( function_exists( 'yoast_breadcrumb' ) ) {
  yoast_breadcrumb( '<nav aria-label="Breadcrumb">', '</nav>' );
}
?>

Make sure only one source prints breadcrumb schema. A theme and a plugin both adding BreadcrumbList gives two different trails. Edit a child theme, never the parent theme, or updates will remove your change.

Shopify

Some themes have a breadcrumb setting; many, including Dawn, do not. Create a snippet called breadcrumbs.liquid:

<nav aria-label="Breadcrumb">
  <ol>
    <li><a href='{{ routes.root_url }}'>Home</a></li>
    {%- if template contains 'product' and collection -%}
      <li><a href='{{ collection.url }}'>{{ collection.title }}</a></li>
      <li><a href='{{ product.url }}' aria-current="page">{{ product.title }}</a></li>
    {%- elsif template contains 'product' -%}
      <li><a href='{{ product.url }}' aria-current="page">{{ product.title }}</a></li>
    {%- elsif template contains 'collection' -%}
      <li><a href='{{ collection.url }}' aria-current="page">{{ collection.title }}</a></li>
    {%- endif -%}
  </ol>
</nav>

Render it with {% render 'breadcrumbs' %} in your product and collection sections. A product only has a collection object when the visitor arrived through a collection URL, which is why the snippet falls back to Home and the product. See building schema on Shopify for the matching JSON-LD.

Hand-coded and framework sites

Build the trail from one data source, such as the URL path or your page tree, and generate both the HTML and the JSON-LD from that same array. That way the two can never disagree.

A worked example

Example Bakery sells cakes online. Its product URLs look like /cakes/birthday/chocolate-fudge/, but product pages have no breadcrumbs, and its theme prints a BreadcrumbList with only Home and the product name.

  1. It decides the hierarchy: Home, then Cakes, then the cake type, then the product, using one primary category per product.
  2. It adds the accessible HTML trail above the product heading, with separators drawn in CSS.
  3. It switches off the theme's breadcrumb schema and outputs a new block from the same data that builds the visible trail.
  4. The Rich Results Test shows one valid Breadcrumbs item with four positions; the visible trail and the markup name the same pages.
  5. A screen reader announces Breadcrumb, navigation, list, 4 items, and the last item is read as the current page.

Within a few weeks the Breadcrumbs report in Search Console lists the product pages as valid, and the category pages gain internal links from every product beneath them.

The fix, step by step

Step 1

Map your site hierarchy

List your main sections and the levels beneath them, for example Home, then Cakes, then Birthday cakes, then individual products. Give every page one parent, and choose a primary category for anything that sits in two. Check each level has a real page that loads with a 200 status. You are ready to move on when you can write the full trail for any page on the site without having to choose between two different paths.

Step 2

Check what your platform offers

Before writing code, look in your theme settings, page builder and SEO plugin for a breadcrumbs option. On WordPress, check Yoast or Rank Math settings; on Shopify, check the theme editor for a breadcrumb section. Note whether the option outputs only the visible trail, only schema, or both. Search the page source for BreadcrumbList to see whether schema is already being printed, so you do not end up with two competing trails.

Step 3

Add the accessible HTML trail

Place a nav element with aria-label="Breadcrumb" above the main heading of each template, containing an ordered list of links from Home to the current page. Mark the last item with aria-current="page" or leave it unlinked. Use the plugin function, Liquid snippet or template partial that fits your platform. Load a product and a category page and confirm the trail appears, each link works and the last item is the page you are on.

Step 4

Style the separators in CSS

Remove any separator characters typed into the HTML and draw them with CSS instead, using li + li::before with a content value such as a slash or an arrow. Add flex-wrap: wrap so long trails wrap on phones. Keep the text size readable and the links clearly clickable. Check on a narrow screen in Chrome DevTools device mode that the trail wraps neatly and does not push the page wider than the viewport.

Step 5

Add matching BreadcrumbList schema

Output a JSON-LD block of type BreadcrumbList with one ListItem per level, each with a position starting at 1, a name matching the visible label and an item holding the full canonical URL. The last item can omit item. Generate it from the same data as the visible trail. If a theme or second plugin also prints breadcrumb schema, switch one off so each page has exactly one BreadcrumbList.

Step 6

Test the markup

Run a product, a category and a post through Google's Rich Results Test. Each should show one valid Breadcrumbs item with the positions and names you expect. Open the item and compare its URLs with the visible links. Fix any critical issues, such as a missing item on a middle level or positions out of order. Then check the same URLs in the Schema Markup Validator to catch any misspelt property names.

Step 7

Test with a screen reader

Turn on NVDA on Windows or VoiceOver on a Mac or iPhone and move through the page by landmarks. The trail should be announced as a breadcrumb navigation, then as a list with the right number of items, and the last item as the current page. Separators should not be read aloud. If the landmark is not named, check the aria-label is on the nav element itself and not on the list.

Step 8

Monitor in Search Console

After Google recrawls your pages, open the Breadcrumbs report under Enhancements in Search Console. It lists valid and invalid items and groups invalid ones by issue, with example URLs. Fix any issues in the template, then click Validate fix. Inspect a sample page with URL Inspection to confirm Google detected the breadcrumb item. Recheck the report after any change to categories, URLs or your theme.

Edge cases worth knowing

Keeping breadcrumbs accurate

Questions and answers

1. What is breadcrumb functionality on a website?

Breadcrumb functionality is a small trail of links, usually above the page heading, that shows where the current page sits in the site and lets visitors move back up a level in one click. A typical trail reads Home, then a category, then a subcategory, then the current page. It helps visitors who land deep in a site from search, adds descriptive internal links to parent pages, and, with BreadcrumbList structured data, tells search engines how the site is organised.

2. How do I create breadcrumbs for my website?

Create breadcrumbs by adding an ordered list of links inside a nav element named Breadcrumb, running from the home page to the current page, then adding matching BreadcrumbList structured data. On WordPress, Yoast SEO and Rank Math can output both once you enable breadcrumbs in their settings. On Shopify, use a theme setting or a Liquid snippet. On custom sites, generate the trail and the schema from the same page data so they always match.

3. Do breadcrumbs help SEO?

Breadcrumbs help SEO indirectly, by adding clear internal links to category pages and by making the site structure easy for crawlers to understand. They are not a direct ranking factor. With BreadcrumbList markup, Google may show the trail in desktop results instead of a bare URL, which can make a listing easier to read. The bigger gains are usually for visitors, who find related pages faster, and for category pages, which gain links from every page beneath them.

4. Where should breadcrumbs go on a page?

Breadcrumbs should go near the top of the page, after the site header and main menu and just above the main heading. That is where visitors expect them and where they are found quickly. Keep them on every page except the home page, in the same position on each template. For accessibility, place any skip to content link before the trail, and wrap the trail in a named nav element so screen reader users can jump to it.

5. Why are my breadcrumbs not showing in Google?

Breadcrumbs in Google search results are now shown on desktop only; since early 2025 mobile results show the site name and domain instead. If they are missing on desktop as well, test the page in the Rich Results Test for a valid Breadcrumbs item. Common faults are missing item URLs on middle levels, positions out of order, a trail that differs from the visible one, or two competing BreadcrumbList blocks from a theme and a plugin.

6. Should the last breadcrumb be a link?

The last breadcrumb can either be plain text or a link marked with aria-current set to page; both are accepted patterns. The W3C ARIA Authoring Practices example uses a link with aria-current, which lets screen readers announce it as the current page. In the matching BreadcrumbList schema, Google allows the item URL to be omitted for the last element. What matters most is that the current page is clearly marked and that every earlier level links to a live page.

7. Do I need breadcrumbs on a small website?

A small website with only one or two levels usually does not need breadcrumbs, because the main menu already shows where everything is. Breadcrumbs earn their place once you have categories with pages beneath them, such as a shop, a blog with sections or a service business with several locations. If you are unsure, look at whether visitors could land on a page from search and not know which section it belongs to. If so, breadcrumbs will help.

Check your breadcrumbs and internal links

The internal links checker on aiwebpageseo.com crawls your pages, shows which have no breadcrumb trail, finds trail links that redirect or break, and compares the visible trail with the BreadcrumbList markup.

Open Internal Link Fixes โ†’
๐Ÿ’ฌ Got a problem?
Related Guides: All Internal Link Fixes  ·  Breadcrumbs in search results  ·  Breadcrumb structured data issues  ·  Internal links guide  ·  How to test schema markup  ·  Learning Hub

About aiwebpageseo

aiwebpageseo.com is a data-driven SEO and AEO (Answer Engine Optimisation) platform providing a free suite of technical SEO tools. Rather than relying on AI-theorised assumptions, the platform analyses live URL performance, delivering objective diagnostics, page speed metrics, CLS debugging, and site crawl data alongside actionable technical tutorials.