What do breadcrumbs do for SEO?
Breadcrumb navigation is the short row of links above a page's title: Home, then Blog, then a category, then the page itself. It does two jobs at once. For a visitor, it answers where am I and gives a one-click route back up. For Google, each crumb is a normal link to a parent page, which is why breadcrumbs sit inside the internal link fixes on WordPress I make before I think about markup.
Across a whole site that adds up. Every post in a category links to that category page, and every category page links to the blog index, so the parent pages collect a link from each child without anyone writing it by hand. That's also why the way you set up WordPress tags and categories decides what the trail can say.
The markup is the second job. Google's breadcrumb documentation says Google Search uses breadcrumb markup in the body of a web page to categorize the information from the page in search results. BreadcrumbList is the structured data type that carries it: the same trail, written as an ordered list Google can read without guessing from the HTML.
Where the trail shows in results has changed, so I check Google's pages on the day. On 22 January 2025 Google updated the breadcrumb documentation to say they only appear on desktop search results, not mobile, because they get truncated on smaller screens. I won't promise a trail on desktop either. What I can control is a correct trail and correct markup.
What are breadcrumbs in SEO, and which type should WordPress use?
In SEO, breadcrumbs are the trail of links that shows where a page sits in a site, plus the markup that describes that trail to search engines. Yoast and Semrush both sort them into three types of breadcrumbs, and only one of them does both SEO jobs well.
| Type | What the trail shows | Where I'd use it |
|---|---|---|
| Hierarchy based | Where the page sits in the site: Home, Blog, category, post | Every WordPress site. It's the only type that links each page to a real parent |
| Attribute based | The filters a shopper picked, like category, size and colour | Next to a hierarchy trail on a store's filtered listings, never instead of it |
| History or path based | The pages this visitor clicked through to get here | Almost nowhere. It changes per visitor, so it can't describe the site to Google |
So on WordPress I use hierarchy based breadcrumbs, with an attribute trail only on a store that filters products. There are also pages where I leave breadcrumbs off: the homepage, a one-page site and a landing page with no parent. A trail there has nothing to point up to.
Which trail should a page show?
Google's documentation recommends breadcrumbs that represent a typical user path to a page, instead of mirroring the URL structure. The question is what a reader would click through to reach the page from the homepage.
This site is my own example. A post here lives at /blog/ followed by its slug, so the URL is two levels deep. Its trail has four steps: Home, then the blog index, then the post's category, then the post. The category isn't in the address, but it's where the post belongs, so it's in the visible trail and in the BreadcrumbList.
| Page type | Trail I use | Why |
|---|---|---|
| Post in one category | Home, Blog, category, post | The category page is the post's real parent and collects a link from it |
| Post filed in several categories | Home, Blog, primary category, post | One trail per page, so I set a primary category instead of letting the plugin pick |
| Page with a parent page | Home, parent page, child page | Page parents are the hierarchy the owner already chose in WordPress |
| WooCommerce product | Home, primary product category, product | Shoppers move between categories, so the trail should hand them one |
| Tag archive | Never a step in any trail | Tags are loose labels, a post can carry ten of them, and none is its parent |
Tags are the row I'm strict about. A trail through a tag archive gives it a link from every tagged post, and a thin tag page with dozens of links in can start showing for the same query as the post it lists. If Search Console already shows that kind of split, checking which URLs share the impressions tells me whether the archive is the problem.
Rather have me do this? One person, whole job.
Book a call on UpworkHow I add breadcrumbs to a WordPress site, step by step
On an existing WordPress site the SEO plugin's nearly always there already, so the job is configuring and placing what it offers, not adding another plugin. New builds get one of the SEO plugins for WordPress I've compared. Here are the seven steps as I take them.
- Step 01
Find every trail the site already prints
I open the source of a post, a page and a category archive and search for BreadcrumbList. A theme, an SEO plugin and a page builder widget can each print a trail, and two running together is how the markup ends up disagreeing with itself.
- Step 02
Pick one source and turn it on
Usually that's the SEO plugin. In Yoast SEO the switch is under Settings, then Advanced, then Breadcrumbs, labelled Enable breadcrumbs for your theme. In Rank Math it's General Settings, then Breadcrumbs, and Rank Math's guide says to turn on the Schema module first, plus Advanced Mode if the settings don't show. If the theme prints its own trail as well, I turn that one off.
- Step 03
Put the visible trail in the template
Yoast offers a Yoast Breadcrumbs block, the
[wpseo_breadcrumb]shortcode and theyoast_breadcrumb()function. Rank Math has the[rank_math_breadcrumb]shortcode andrank_math_the_breadcrumbs(). I place it once, above the H1, in a child theme or the block theme's template, so nobody has to paste a shortcode into each post. - Step 04
Set a primary category on every post
A post filed in two or three categories needs one of them marked primary, or the plugin picks for it. Rank Math's Show Category(s) option uses the primary category when a post has several. I also check no trail runs through Uncategorized, which is nobody's idea of a parent.
- Step 05
Keep the labels short and honest
The home crumb says Home, not the site title with keywords packed in, and category names read the way the menu reads them. On long titles I shorten the last crumb or hide it, and Rank Math has a Hide Post Title option for exactly that.
- Step 06
Test one URL per template
I run a post, a page, a category archive and a product through the Rich Results Test, then read each page's visible trail against its markup. Same names, same order, same URLs. If they don't match, the template's wrong, so one fix covers every page built from it.
- Step 07
Watch the report after launch
Google's page points to the Rich result status report in Search Console for valid and invalid items. I check it after launch and after any theme or plugin update, since that's when a working trail quietly breaks.
Yoast's help page says its breadcrumbs output JSON-LD data in the source code. That markup can be there with no visible trail at all, so I always place the visible trail too.
What does the BreadcrumbList markup need?
Not much, and that's what makes breadcrumb schema easy to get right. Google's documentation asks for a BreadcrumbList holding at least two ListItem entries. Each one carries its position in the trail, a name and the URL of the page it stands for, in order from the top of the hierarchy down to the current page.
| Property | What Google's page says | What I check |
|---|---|---|
| itemListElement | Required: the breadcrumbs, listed in a specific order | At least two items, top level first |
| position | Required: the crumb's place in the trail | Numbers run 1, 2, 3 with no gaps or repeats |
| name | Required: the title of the crumb shown to the user | Matches the visible crumb word for word |
| item | Required, except on the last item, where Google uses the page's own URL | Absolute URLs on the canonical host, each one returning 200 |
On this site the markup comes from one small function in the build, and every trail gets its own @id ending in #breadcrumb so the rest of the page's structured data can point at it. On WordPress I keep the trail as one node in the page's graph where the plugin allows it. Fitting it into that graph is part of the structured data help for WordPress I do, because a trail that contradicts the page's other markup is still a contradiction.
The visible trail has an accessibility job too. The W3C's breadcrumb pattern puts the trail inside a navigation landmark labelled with aria-label, and marks the link to the current page with aria-current set to page. This site does both: its trail is a nav labelled Breadcrumb, and the last crumb carries aria-current, so a screen reader announces where the page sits.
Where do breadcrumbs go wrong?
Most of these faults don't show up as errors anywhere. They turn up when someone reads the source and clicks the crumbs.
- i.
Two trails on one page
The theme prints one and the SEO plugin prints another, with different names or different parents. Google gets two paths that disagree, and the visitor sees only one of them. I keep a single source.
- ii.
Markup that doesn't match the page
The visible crumb says Guides and the markup says Resources, or the markup has a level the page doesn't show. I treat any mismatch as a bug.
- iii.
Tags, dates or Uncategorized in the trail
None of these is a real parent. They add links to thin archives and tell visitors nothing about where the page sits.
- iv.
Crumbs that point at redirects
Rename a category base or change permalinks, and every trail still pointing at the old address sends each click through a 301. The same happens after a platform move, which is why the redirect map for a Wix to WordPress move includes category and tag archives. I fix the trail's source, then check each crumb answers with a 200.
- v.
A trail with one crumb
Home on its own isn't a trail. Google asks for at least two ListItem entries, so I leave the homepage without breadcrumbs and start the trail one level down.
If your categories, your trail and your markup each tell a different story about the site, that's the structure work I do remotely: one trail source, parents that make sense, markup that matches, and the checks after the change goes live.
Book a call on Upwork
