Breadcrumbs in Joomla
Breadcrumbs look like the simplest thing on a Joomla page: a small trail of links near the top that says "Home / News / Joomla 6 Released". Yet that little trail is built from the menu tree, the active menu item, and sometimes the component you are viewing. Once you see how Joomla assembles it, you can fix broken trails, style them properly, and turn them into real SEO value.
This article explains how Joomla breadcrumbs really work. It covers the basics for website owners and editors, the practical setup for administrators, and the technical details for developers. You will learn what the Pathway is, how the Breadcrumbs module turns it into a visible trail, how components add their own steps, how the trail becomes structured data for search engines, and how to avoid the common mistakes.
Breadcrumbs are not a setting you type in. They are a live picture of where the current page sits in your menu tree.
The goal is simple: help you understand breadcrumbs well enough to use them with confidence.
1. The Basics
1.1 What is a Breadcrumb Trail?
A breadcrumb trail is a row of links that shows the path from the home page down to the page a visitor is viewing. It usually looks like this:
Home → Products → Laptops → ThinkPad X1
Each step except the last is a link. The last step is the current page, so it is normally plain text. The name comes from the fairy tale: a trail of crumbs that shows the way back.
1.2 Why Breadcrumbs Matter
Breadcrumbs do three useful jobs at once:
- Orientation: visitors see where they are in the site structure.
- Navigation: visitors can jump back up to any parent level in one click.
- SEO: search engines read the trail, show it in results, and understand your site hierarchy.
1.3 Where Do Breadcrumbs Come From in Joomla?
This is the part newcomers miss. In Joomla you do not write the trail by hand. Joomla keeps an internal object called the Pathway. The Pathway is filled automatically:
- The active menu item and its parent menu items form the base of the trail.
- The component you are viewing (for example an article) can add more steps, such as the category and the article title.
A separate module, mod_breadcrumbs, reads the Pathway and renders it as a visible trail. No module means no visible breadcrumbs, even though the Pathway still exists.
The Pathway is the data. The Breadcrumbs module is the display.
1.4 Anatomy of a Breadcrumb Trail
A rendered trail in Joomla 6 has these parts:
| Part | What it is |
|---|---|
| "You are here:" label | An optional prefix in front of the trail. |
| Home crumb | An optional first link to the site home page. |
| Middle crumbs | One link per parent menu item or category, each clickable. |
| Last crumb | The current page, shown as plain text (optional). |
2. Showing Breadcrumbs on Your Site
2.1 Publish the Breadcrumbs Module
Breadcrumbs appear only when you publish the Breadcrumbs module. To add it, go to:
System → Site Modules → New → Breadcrumbs
Then set three things:
- Title: for example "Breadcrumbs". You can hide the title on the frontend.
- Position: choose a template position near the top of the content, such as
breadcrumbsin the default Cassiopeia template. - Status: set it to Published.
2.2 Choose Where It Appears
Like every module, the Breadcrumbs module has a Menu Assignment tab. You decide where the trail shows:
- On all pages (the usual choice).
- On all pages except the home page (very common, because a trail on the home page is pointless).
- Only on selected pages.
A clean default is "On all pages" combined with hiding the Home crumb, or "All pages except Home".
2.3 Confirm the Template Position Exists
If you publish the module but see nothing, the chosen position may not exist in your template. You can preview positions by enabling Preview Module Positions in the Templates options, then append ?tp=1 to a frontend URL (spoiler: you can type anything except 0, ?tp=peter also works!). The Cassiopeia template ships a dedicated breadcrumbs position for exactly this purpose.
3. Module Options Explained
The Breadcrumbs module has a small but important set of options. Each one maps directly to a parameter in the module configuration.
3.1 Basic Options
| Option | Parameter | What it does |
|---|---|---|
| "You are here" | showHere |
Shows the "You are here:" label before the trail. When off, Joomla shows a small location icon instead. |
| Home | showHome |
Adds the Home link as the first crumb. |
| Text for Home Entry | homeText |
Overrides the word "Home". Leave it empty to use the language default. |
| Last | showLast |
Shows the current page as the final crumb. Turn it off to end the trail at the parent. |
3.2 Advanced Options
| Option | Parameter | What it does |
|---|---|---|
| Alternative Layout | layout |
Selects a layout file, including one from a template override. |
| Module Class Suffix | moduleclass_sfx |
Adds a CSS class so you can style this instance. |
| Caching | cache |
Use global caching or none. |
| Cache Time | cache_time |
How long, in minutes, to keep the cached output. |
There is also a hidden parameter, cachemode, fixed to itemid. This makes Joomla cache one version of the trail per menu item, which is the correct behaviour because the trail changes per page.
3.3 The "Show Last" Trick
Many designers turn showLast off. The current page already has an <h1> heading, so repeating its title in the trail can feel redundant. Turning it off ends the trail at the last parent. It is a matter of taste, but it keeps the trail shorter.
4. How the Trail is Built: the Pathway
4.1 The Pathway Object
Behind every frontend page, Joomla keeps a Pathway object. It is a simple list. Each entry has two fields:
name -- the visible label of the crumb
link -- the URL the crumb points to (empty for the current page)
The class lives in Joomla\CMS\Pathway\Pathway, and the frontend uses the subclass SitePathway. You reach the active instance from the application:
$pathway = $app->getPathway();
4.2 The Menu Tree Fills the Base
When a page loads, Joomla looks at the active menu item. Every menu item knows its ancestors through a tree property: the chain of parent items from the top down to itself. SitePathway walks that tree and adds one crumb per ancestor menu item.
One important detail: if the active item is the home page, Joomla adds nothing. The home page is never part of the trail body, because the optional Home crumb already covers it.
4.3 Special Menu Item Types
Not every menu item becomes a clickable crumb. SitePathway treats some types differently:
| Menu item type | Crumb behaviour |
|---|---|
| Separator | Shown as a label, no link. |
| Heading | Shown as a label, no link. |
| URL | Linked. Joomla adds the Itemid for internal links. |
| Alias | Linked to the aliased item using its aliasoptions parameter. |
| Component | Linked, with the Itemid appended. |
This is why a Heading used as a dropdown parent shows up in the trail as plain text: it has no real page to link to.
Back to top5. How Components Extend the Trail
5.1 The Menu Tree is Only the Start
The menu tree gives the base trail, but it stops at the menu item. A Single Article menu item, for example, does not know which article you opened from a category blog. So components add their own crumbs at runtime.
5.2 Articles Add Category and Title Crumbs
When you open an article that is not directly linked to its own menu item, the Articles component (com_content) builds the missing steps. It starts from the article, walks up the category tree to the menu item's category, and adds each level. In code, the Article view does this:
$pathway = $app->getPathway();
$path = [['title' => $this->item->title, 'link' => '']];
$category = Categories::getInstance('Content')->get($this->item->catid);
while ($category !== null && $category->id != $id) {
$path[] = ['title' => $category->title, 'link' => RouteHelper::getCategoryRoute($category->id)];
$category = $category->getParent();
}
$path = array_reverse($path);
foreach ($path as $item) {
$pathway->addItem($item['title'], $item['link']);
}
The result is a trail like Home → News → Products → Laptops, even though only "News" was a real menu item.
5.3 Why This Matters for Your Content
Because components fill the gap from the menu item down to the content, the quality of your trail depends on two things:
- A clean category tree, since article breadcrumbs follow the category parents.
- A correct Itemid, since the starting menu item decides where the component trail begins.
If Joomla guesses the wrong Itemid, the trail can start in the wrong branch. This is the single most common cause of "weird breadcrumbs".
6. Breadcrumbs and the Itemid
6.1 The Itemid Sets the Starting Point
Every frontend page is tied to a menu item through the Itemid parameter. The Pathway uses the active menu item to build its base, so the Itemid directly decides:
- Which parent menu items appear as crumbs.
- Where the component trail attaches.
- Whether the Home crumb is suppressed (on the home item itself).
6.2 What Goes Wrong Without a Clear Itemid
If a link to an article has no Itemid, Joomla's router guesses one. A wrong guess produces:
- A trail that starts in the wrong menu branch.
- Missing or doubled crumbs.
- A different trail for the same article reached from two places.
6.3 How to Inspect It
Before SEF rewriting hides it, the Itemid is the last number in the query string:
index.php?option=com_content&view=article&id=42&Itemid=123
When a breadcrumb trail looks wrong, check the Itemid first. The fix is usually to link to the content through the right menu item, or to create a dedicated menu item for that page.
7. From URL to Breadcrumb: the Full Pipeline
7.1 The Request Flow, Step by Step
A breadcrumb trail is the last step of a longer process. When a visitor opens a page, Joomla runs roughly these steps:
- The SiteRouter receives the request URL, for example
/news/products/laptops. - The router parses the URL and resolves the
Itemid, which sets the active menu item. SitePathwaybuilds the base trail by walking the active menu item's parenttree, skipping the home item.- The matching component runs. If needed, it calls
addItem()to append deeper crumbs, such as the category chain and the article title. - mod_breadcrumbs asks its helper for the finished list and, if enabled, prepends the Home crumb.
- The layout renders the trail as an ordered list and emits the schema.org structured data.
This is why breadcrumbs depend so heavily on routing and menu configuration. The module itself does almost nothing: by the time it runs, the trail is already decided.
7.2 The Sequence at a Glance
The same flow as a diagram, from the browser request down to the HTML:
Browser request
↓
SiteRouter resolves the Itemid and the active menu item
↓
SitePathway adds the parent menu items as crumbs
↓
Component addItem() for category and article crumbs
↓
mod_breadcrumbs reads the Pathway, prepends the Home crumb
↓
Layout (default) renders the list and the schema.org JSON-LD
↓
HTML in the page
7.3 Why the Order Matters
Each stage can only work with what the earlier stages produced. A wrong Itemid in step 2 sends the rest of the chain down the wrong branch. A component that forgets to call addItem() in step 4 leaves the deep crumbs missing. When you troubleshoot, start at the top of this list and work down: router first, module last.
8. Under the Hood (Developer View)
8.1 The Pathway API
The Pathway exposes a small, stable API. You can read or change the trail from a plugin or a custom component:
use Joomla\CMS\Factory;
$app = Factory::getApplication();
$pathway = $app->getPathway();
// Read
$items = $pathway->getPathway(); // array of objects with name + link
$names = $pathway->getPathwayNames(); // array of just the names
// Write
$pathway->addItem('Downloads', 'index.php?option=com_downloads&view=list&Itemid=55');
$pathway->setItemName(2, 'Renamed crumb');
$pathway->setPathway($newArrayOfItems); // replace the whole trail
Each item is a plain stdClass with a name and a link. An empty link means the crumb renders as text, not a hyperlink.
8.2 Where SitePathway Builds the Base
The frontend subclass Joomla\CMS\Pathway\SitePathway builds the base trail in its constructor. It reads the active menu item, skips the home item, and walks the tree property, choosing a link per item type (separator, heading, url, alias, or component). Everything after that is added by components through addItem().
8.3 A Plugin Example
A System plugin can adjust the trail late in the request, for example on the onAfterDispatch or onAfterRoute event:
public function onAfterRoute(): void
{
$app = $this->getApplication();
if ($app->isClient('site')) {
$pathway = $app->getPathway();
$pathway->addItem('Special Offer', '');
}
}
This is how third-party extensions insert their own crumbs without touching core files.
8.4 There is No Breadcrumbs Table
The trail is never stored. It is rebuilt on every request from the live menu tree and the current content. Breadcrumbs therefore have no dedicated database table. Instead, the module leans on a handful of core tables. The next subsections list the ones that matter.
8.5 The #__menu Table
This is the most important table, because it holds the menu tree that forms the base of every trail. The relevant columns are:
id -- menu item id, used as the Itemid
parent_id -- the parent menu item
level -- depth in the tree
lft, rgt -- Nested Set Model boundaries
path -- full SEF path (parent/child/grandchild)
alias -- the URL segment
type -- component | url | alias | separator | heading
component_id -- the linked component
link -- the underlying index.php?option=... query
The lft and rgt columns implement the Nested Set Model. A parent's range always wraps its children, so Joomla can fetch a whole branch of ancestors in one query, with no recursion. That is what makes building the trail from the menu tree fast.
8.6 The #__modules and #__modules_menu Tables
The Breadcrumbs module itself is a normal module, so its configuration lives in #__modules:
| Column | What it holds |
|---|---|
title |
The module title. |
position |
The template position it renders in. |
params |
A JSON blob with the options (showHome, showLast, and so on). |
published, access, language |
Status, access level, and language. |
The companion table #__modules_menu maps each module to the menu items it appears on. For breadcrumbs, this is what your Menu Assignment choice writes:
moduleid -- which module
menuid -- which menu item (Itemid)
positive = "show on this item"
negative = "show on all except these items"
0 = "all pages"
So "All pages except Home" is stored here as a negative row for the home menu item.
8.7 Supporting Tables
#__extensions: registersmod_breadcrumbsas an installed extension, with its enabled state and default parameters.#__assets: holds the ACL records (the access rules) used across Joomla, including the module's access level.
None of these store the trail itself. Together they describe the menu structure, the module, and who may see it, and Joomla rebuilds the breadcrumbs from them on every request.
Back to top9. The Module Helper and Rendering
9.1 From Pathway to HTML
The Breadcrumbs module turns the Pathway into HTML in three steps:
- The module Dispatcher asks the helper for the list of crumbs.
- The BreadcrumbsHelper reads the Pathway and, if
showHomeis on, prepends the Home crumb. - The layout file (
tmpl/default.php) renders the list as an ordered list of links.
9.2 The Modern Helper Call
In Joomla 6 the helper is a normal service, not a static call. The modern way to get the crumbs is:
$crumbs = Factory::getApplication()
->bootModule('mod_breadcrumbs', 'site')
->getHelper('BreadcrumbsHelper')
->getBreadcrumbs($params, Factory::getApplication());
The old static methods BreadcrumbsHelper::getList() and getHome() still exist, but they are deprecated since 4.4.0 and will be removed in Joomla 7.0. New code should use the instance methods getBreadcrumbs() and getHomeItem().
9.3 The Home Crumb Logic
The helper builds the Home crumb from the default menu item for the current language:
$home = $menu->getDefault(); // or getDefault($langTag) when multilingual
$item->name = $params->get('homeText', 'Home');
$item->link = $home->link . '&Itemid=' . $home->id;
If showHome is off, the helper still computes a fallback Home item, which the layout uses only for structured data (see the SEO section). That way the trail can hide the Home link visually while keeping it in the machine-readable data.
10. Template Overrides and Styling
10.1 The Default Markup
The Joomla 6 default layout outputs semantic, accessible markup based on Bootstrap classes:
<nav class="mod-breadcrumbs__wrapper" aria-label="Breadcrumbs">
<ol class="mod-breadcrumbs breadcrumb px-3 py-2">
<li class="mod-breadcrumbs__item breadcrumb-item">
<a class="pathway" href="/"><span>Home</span></a>
</li>
<li class="mod-breadcrumbs__item breadcrumb-item active">
<span>Current Page</span>
</li>
</ol>
</nav>
The <nav> wrapper with an aria-label tells screen readers this is a navigation landmark. The last crumb gets the active class. If you want an even stronger accessibility signal, an override can add aria-current="page" to the last crumb.
10.2 Creating an Override
To change the markup, never edit the module. Create a template override instead. For the Cassiopeia template:
templates/cassiopeia/html/mod_breadcrumbs/default.php
Copy the original modules/mod_breadcrumbs/tmpl/default.php into that path, then edit your copy. Joomla loads the override automatically. The Templates manager has a built-in editor that creates this override for you:
System → Site Templates → [your template] → Create Overrides → mod_breadcrumbs
10.3 Styling Without an Override
For simple visual changes you do not need an override at all. Use the Module Class Suffix and target the standard classes in your template CSS:
.mod-breadcrumbs { font-size: 0.9rem; }
.mod-breadcrumbs__item.active span { color: #666; }
.breadcrumb-item + .breadcrumb-item::before { content: "→"; }
Back to top11. Structured Data and SEO
11.1 Breadcrumbs Help Search Engines
Breadcrumbs are one of the cheapest SEO wins in Joomla. They give search engines a clear map of your site hierarchy, and Google often shows the trail instead of the raw URL in search results.
11.2 Built-in Structured Data
The Joomla 6 Breadcrumbs module outputs schema.org BreadcrumbList structured data automatically. It adds a JSON-LD block to the page head, with no configuration needed:
{
"@context": "https://schema.org",
"@type": "BreadcrumbList",
"itemListElement": [
{ "@type": "ListItem", "position": 1,
"item": { "@id": "https://example.test/", "name": "Home" } },
{ "@type": "ListItem", "position": 2,
"item": { "@id": "https://example.test/news", "name": "News" } },
{ "@type": "ListItem", "position": 3,
"item": { "name": "Joomla 6 Released" } }
]
}
Notice that the last item has a name but no @id. Google accepts a URL-less entry only for the current page, and Joomla follows that rule.
11.3 The Home Crumb is Always in the Data
Even when you hide the Home link visually (showHome off), Joomla keeps the home page as position 1 in the structured data through a fallback Home crumb. This gives you a clean visible trail and complete machine-readable data at the same time.
11.4 Test Your Markup
After publishing, validate the output with Google's Rich Results Test or the Schema Markup Validator. A valid BreadcrumbList can earn the breadcrumb display in search results.
12. Multilingual Breadcrumbs
12.1 The Home Crumb per Language
On a multilingual site, each language has its own default (home) menu item. The Breadcrumbs module asks for the default item of the current language:
$home = $menu->getDefault($app->getLanguage()->getTag());
So a Dutch page links the Home crumb to the Dutch home, and an English page to the English home. This only works if every active language has its own default menu item set with the yellow star.
12.2 Avoiding Duplicate Home Entries
On multilingual sites the home menu item can appear twice: once from the Home crumb and once from the menu tree. The default layout detects this and removes the duplicate second entry, so the trail stays clean.
12.3 Translated Labels
Each crumb name comes from the menu item title or the content title in that language, so the trail is translated automatically when your content and menus are properly associated. The word "Home" comes from the language file or from the homeText option, which you can set per module copy and assign per language.
13. Caching
13.1 Per-Itemid Caching
Breadcrumbs change on every page, so caching them needs care. The module uses the itemid cache mode, which stores a separate cached trail for each menu item. This is set as a hidden, fixed parameter and is the correct mode for this module.
13.2 When to Use Module Caching
- For a normal site, leave caching on Use Global and let Joomla manage it.
- If you insert dynamic crumbs from a plugin based on the logged-in user, set caching to No Caching so the trail is always fresh.
- Remember that component-added crumbs (like article titles) depend on the full URL, not only the
Itemid, so heavy caching of a single page that serves many articles can show a stale trail. The default per-Itemid behaviour handles standard cases correctly.
14. Common Mistakes and Pitfalls
14.1 No Breadcrumbs Appear
Symptom: there is no trail anywhere on the site.
Fix: publish the Breadcrumbs module, set it to a real template position (such as breadcrumbs in Cassiopeia), and assign it to the right pages.
14.2 The Trail Starts in the Wrong Branch
Symptom: an article shows Home → Wrong Section → Article.
Fix: the wrong Itemid is active. Link to the content through the correct menu item, or give the page its own menu item. Check the category tree too, since article crumbs follow category parents.
14.3 Duplicate Home on Multilingual Sites
Symptom: the trail shows Home → Home → ....
Fix: this happens when the home item appears in both the Home crumb and the menu tree. Modern Joomla removes the duplicate automatically; if you use a custom override, make sure it keeps the de-duplication logic from the default layout.
14.4 A Heading Crumb Has No Link
Symptom: a middle crumb is plain text, not a link.
Fix: this is correct behaviour. Menu items of type Heading or Separator have no page, so Joomla renders them as text. If you need a link there, use a real menu item type instead.
14.5 The Last Crumb Repeats the Page Title
Symptom: the trail ends with the same text as the page heading, which feels redundant.
Fix: turn off the Last option (showLast) to end the trail at the parent.
14.6 Edited the Module Instead of an Override
Symptom: custom breadcrumb markup disappears after a Joomla update.
Fix: never edit files in modules/mod_breadcrumbs/. Put your changes in a template override at templates/[template]/html/mod_breadcrumbs/default.php.
15. Best Practices
If you only remember a few things from this article, remember these:
- Publish one Breadcrumbs module and assign it to all pages except the home page.
- Keep a clean, shallow category tree, because article crumbs follow category parents.
- Always link to content through a correct menu item so the
Itemidis stable. - Decide once whether to show the last crumb, and keep it consistent across the site.
- Style and restructure breadcrumbs with a template override, never by editing the module.
- Trust the built-in schema.org output, and validate it with Google's Rich Results Test.
- On multilingual sites, set a default menu item per language so the Home crumb resolves correctly.
16. Quick Reference
SHOW BREADCRUMBS Publish mod_breadcrumbs in a template position
HIDE ON HOME Menu Assignment → All pages except Home
"YOU ARE HERE" Option showHere
HOME CRUMB Option showHome (homeText overrides the word)
LAST CRUMB Option showLast (off = end at parent)
DATA SOURCE $app->getPathway() (Pathway object, not a table)
BASE OF TRAIL Active menu item + its parent tree
EXTRA CRUMBS Components call $pathway->addItem(name, link)
ADD A CRUMB (PHP) $app->getPathway()->addItem('Label', 'index.php?...')
PIPELINE Router → Menu → Component → Pathway → Module → Template
DB TABLES #__menu (tree), #__modules, #__modules_menu
OVERRIDE MARKUP templates/[tpl]/html/mod_breadcrumbs/default.php
STRUCTURED DATA schema.org BreadcrumbList JSON-LD, automatic
CACHING Mode itemid, one cached trail per menu item
DEPRECATED API BreadcrumbsHelper::getList()/getHome() (use instances)
Back to top17. Summary
Joomla breadcrumbs are simple on the surface and clever underneath:
- Pathway: the internal list of crumbs, rebuilt on every request.
- Menu tree: the active menu item and its parents form the base of the trail.
- Components: add deeper crumbs such as category and article titles through
addItem(). - Pipeline: router → menu → component → Pathway → module → template.
- Module:
mod_breadcrumbsreads the Pathway and renders the visible trail. - SEO: the module emits schema.org structured data automatically.
- Itemid: the menu item context that decides where the trail begins.
Once you understand that the trail mirrors your menu and category structure, broken breadcrumbs stop being a mystery. They are almost always a symptom of a wrong Itemid, a messy category tree, or a missing menu item.
If your breadcrumbs look wrong, your navigation feels confusing, or you want clean structured data for better search results, it pays to review your menu structure and routing early. Get the menu tree right, and breadcrumbs take care of themselves.
Back to top

Peter is a Joomla specialist and a Linux admin for fast, secure and scalable websites.
Frequently Asked Questions
Joomla breadcrumbs are navigation aids showing users the path they took, enhancing site usability and SEO.
Breadcrumbs improve internal linking, help search engines understand site structure, and appear in search results for better visibility.
Yes, you can customize breadcrumb style, position, and labels to match your site’s design and user needs.
Yes, Joomla breadcrumbs adapt to responsive layouts, ensuring a smooth experience on all devices.
Breadcrumbs can be enabled via the module manager, where you can configure settings to fit your site’s structure.
No, breadcrumbs are lightweight and do not negatively impact site performance.


