breadcrumbs rich snippets in magento

Merchants often optimise websites for rich snippets as part of the Magento SEO best practices. However, they usually include category and product markup, while others like Magento breadcrumbs rich snippets get overlooked. 

This guide covers everything you need to know about breadcrumbs schema in Magento, breadcrumbs rich snippets, and how to add them to all pages in your Magento store.

Key takeaways
  • Breadcrumbs rich snippets are generated by BreadcrumbList structured data that replaces URLs in search engine results with a clear navigation path.
  • Breadcrumbs, breadcrumb schema, and breadcrumbs rich snippets are three different components of the website's architecture that work together to improve navigation.
  • When implemented correctly, breadcrumb schema helps search engines interpret your store structure, which contributes to breadcrumbs rich snippets on desktop search results.
  • You can add breadcrumb schema in Magento manually with JSON-LD or generate it automatically with a Magefan Rich Snippet extension.
  • You can validate Magento breadcrumb schema with Google's Rich Results Test and the Breadcrumbs report in Google Search Console.

What Are Magento Breadcrumbs Rich Snippets?

Magento breadcrumbs rich snippets are a type of structured data code (Schema.org markup) that helps search engines display a clear navigation path, such as Home > Category > Product, instead of long URLs on the search results page. They are generated from the breadcrumb structured data (JSON-LD or microdata) added to the page. 

By default, Magento provides breadcrumbs for products, categories, and CMS pages. However, there's no default BreadcrumbList schema markup.

magento breadcrumbs rich snippets

An example of a breadcrumbs rich snippet for a product page in Google search results

Note: Google has removed breadcrumbs rich snippets from mobile search results to improve visual layout. So, they are still visible on desktop screens.

What are breadcrumbs in Magento?

Magento breadcrumbs are small navigation links that show visitors their path from the homepage to a product or other page on the website. They are generally displayed near the top of a page and look like: Home > Men > Tops > Jackets > Montana Wind Jacket.

e.g. if a person lands on your product page, breadcrumbs help them quickly go back or navigate across catalog pages without extra clicks. They just need to press any part of the breadcrumb trail (that is, Jackets, Tops, or Men) to jump straight to the category they are interested in.

magento website breadcrumbs

Magento breadcrumbs example

What is a breadcrumb schema?

Breadcrumbs schema (or BreadcrumbList) is a structured data markup added to a page HTML that gives search engines details about the place of the page in the entire store hierarchy. It specifies the breadcrumb links in a standardized machine-readable format that search engines can read.

e.g. the breadcrumbList for the following Magento path Home > Men > Tops > Jackets > Montana Wind Jacket would look like this:

{
  "@context": "https://schema.org",
  "@type": "BreadcrumbList",
  "itemListElement": [
    {
      "@type": "ListItem",
      "position": 1,
      "name": "Home",
      "item": "https://example.com/"
    },
    {
      "@type": "ListItem",
      "position": 2,
      "name": "Men",
      "item": "https://example.com/men"
    },
    {
      "@type": "ListItem",
      "position": 3,
      "name": "Tops",
      "item": "https://example.com/men/tops"
    },
    {
      "@type": "ListItem",
      "position": 4,
      "name": "Jackets",
      "item": "https://example.com/men/tops/jackets"
    },
    {
      "@type": "ListItem",
      "position": 5,
      "name": "Montana Wind Jacket"
    }
  ]
}

As a result, search engines can clearly interpret the path and may display breadcrumbs rich snippets in search results.

Note: adding breadcrumbs schema doesn't guarantee that breadcrumbs rich snippets will appear in search results. It's like a recommendation to search engines that helps them understand the hierarchy, which they may show in search results.

Breadcrumb vs breadcrumb schema vs breadcrumbs rich snippets

Magento breadcrumbs is not the same as breadcrumbs schema and rich snippets. Here are the key differences.

  Breadcrumbs Breadcrumb schema Breadcrumbs rich snippets
What it is A visible trail of links on the page Hidden structured data (JSON-LD) describing that same trail for machines The trail displayed in search results, instead of a raw cluterred URL
Where it lives Near the top of the webpage In the page HTML code, not visible on screen On the search engine results page (desktop)
Who sees it Website visitors Search engines and crawlers People searching on Google
Example Home > Men > Tops > Jackets A BreadcrumbList block in JSON-LD format Home > Men > Tops > Jackets shown under a search result title
Main benefit Faster on-site navigation, fewer clicks Helps engines understand site hierarchy and crawl more efficiently Higher click-through rate, clearer context before clicking
Affects rankings No No, but makes rich snippets possible No, and appearance isn't guaranteed even with valid schema

How to Add Breadcrumbs Rich Snippets to Magento 2?

There are two ways to add breadcrumbs rich snippets to Magento: by adding the required structured data code manually or by using the Magefan Rich Snippets for Magento, which generates and maintains it automatically.

The options depend on the size of your catalog, your technical skills, and the time you can spend on managing structured data.

Add breadcrumb schema in Magento manually

Adding breadcrumbs schema manually requires some technical knowledge since you will need to create a small custom module. Its task is to generate a BreadcrumbList JSON-LD script from existing Magento breadcrumb data. 

Step 1: Create a custom module

Create a module (e.g., Vendor/RichSnippets) and add a di.xml file that attaches a plugin to Magento breadcrumbs block under the following path app/code/Vendor/RichSnippets/etc/frontend/di.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Theme\Block\Html\Breadcrumbs">
        <plugin name="Vendor_RichSnippets::add_breadcrumb_schema" type="Vendor\RichSnippets\Plugin\AddBreadcrumbJsonLd" />
    </type>
</config>

Step 2: Write a plugin

Create a plugin that reads existing breadcrumbs in your store using getCrumbs(), converts them into BreadcrumbList schema, and then injects the JSON-LD script into the page.

For that, place the following code in app/code/Vendor/RichSnippets/Plugin/AddBreadcrumbJsonLd.php:

<?php
namespace Vendor\RichSnippets\Plugin;

use Magento\Catalog\Model\Category;
use Magento\Catalog\Model\Product;
use Magento\Catalog\Model\ResourceModel\Category\CollectionFactory as CategoryCollectionFactory;
use Magento\Framework\Registry;
use Magento\Store\Model\StoreManagerInterface;
use Magento\Theme\Block\Html\Breadcrumbs;
use ReflectionProperty;

class AddBreadcrumbJsonLd
{
    /**
     * @var Registry
     */
    private $registry;

    /**
     * @var StoreManagerInterface
     */
    private $storeManager;

    /**
     * @var CategoryCollectionFactory
     */
    private $categoryCollectionFactory;

    /**
     * @param Registry $registry
     * @param StoreManagerInterface $storeManager
     * @param CategoryCollectionFactory $categoryCollectionFactory
     */
    public function __construct(
        Registry $registry,
        StoreManagerInterface $storeManager,
        CategoryCollectionFactory $categoryCollectionFactory
    ) {
        $this->registry = $registry;
        $this->storeManager = $storeManager;
        $this->categoryCollectionFactory = $categoryCollectionFactory;
    }

    public function afterToHtml(Breadcrumbs $subject, string $result): string
    {
        $jsonLd = $this->buildJsonLd($subject);

        if (empty($jsonLd)) {
            return $result;
        }

        $script = '<script type="application/ld+json">'
            . str_replace('</', '<\/', json_encode($jsonLd, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE))
            . '</script>';

        return $result . $script;
    }

    private function buildJsonLd(Breadcrumbs $subject): array
    {
        $crumbs = $this->getCrumbs($subject) ?: $this->getProductFallbackCrumbs();

        if (!$crumbs || !is_array($crumbs)) {
            // No crumbs to render — this is expected on the homepage,
            // where Magento doesn't output a breadcrumb trail at all.
            return [];
        }

        $itemListElement = [];
        $position = 1;

        foreach ($crumbs as $crumbInfo) {
            $item = [
                '@type' => 'ListItem',
                'position' => $position,
                // Labels are often \Magento\Framework\Phrase objects, not
                // strings — cast explicitly or json_encode() will output {}.
                'name' => (string) $crumbInfo['label'],
            ];

            if (!empty($crumbInfo['link']) && empty($crumbInfo['last'])) {
                $item['item'] = $crumbInfo['link'];
            }

            $itemListElement[] = $item;
            $position++;
        }

        return [
            '@context' => 'https://schema.org',
            '@type' => 'BreadcrumbList',
            'itemListElement' => $itemListElement,
        ];
    }

    /**
     * Breadcrumbs stores crumbs in a protected $_crumbs property and never
     * exposes a public getter — it only pushes them into the phtml scope via
     * assign('crumbs', ...), which lands in $_viewVars, not block data. So
     * there's nothing to call; read the property directly. This runs in
     * afterToHtml, i.e. after _toHtml() already stamped first/last flags on
     * it, so it's the exact same array the template rendered from.
     */
    private function getCrumbs(Breadcrumbs $subject)
    {
        $property = new ReflectionProperty(Breadcrumbs::class, '_crumbs');
        $property->setAccessible(true);

        return $property->getValue($subject);
    }

    /**
     * Product pages render breadcrumbs entirely client-side via the
     * mage/breadcrumbs JS widget (fed from browser-cached category data),
     * so $_crumbs is always empty here — there's nothing added server-side
     * to reflect. Build the trail ourselves from the product's own category
     * assignment instead of depending on JS/session state, so crawlers get
     * a breadcrumb regardless of how the product URL was reached.
     */
    private function getProductFallbackCrumbs(): ?array
    {
        /** @var Product|null $product */
        $product = $this->registry->registry('current_product');

        if (!$product) {
            return null;
        }

        $crumbs = [
            ['label' => __('Home'), 'link' => $this->storeManager->getStore()->getBaseUrl()],
        ];

        $category = $this->registry->registry('current_category') ?: $this->getProductCategory($product);

        if ($category) {
            $pathIds = array_reverse(explode(',', $category->getPathInStore()));
            $parentCategories = $category->getParentCategories();

            foreach ($pathIds as $categoryId) {
                if (isset($parentCategories[$categoryId]) && $parentCategories[$categoryId]->getName()) {
                    $crumbs[] = [
                        'label' => $parentCategories[$categoryId]->getName(),
                        'link' => $parentCategories[$categoryId]->getUrl(),
                    ];
                }
            }
        }

        $crumbs[] = ['label' => $product->getName(), 'last' => true];

        return $crumbs;
    }

    /**
     * Pick the most specific (deepest) active category assigned to the
     * product to stand in for the missing current_category registry entry.
     */
    private function getProductCategory(Product $product): ?Category
    {
        $categoryIds = $product->getCategoryIds();

        if (empty($categoryIds)) {
            return null;
        }

        $collection = $this->categoryCollectionFactory->create()
            ->addAttributeToSelect(['name', 'url_key', 'url_path'])
            ->addIdFilter($categoryIds)
            ->addAttributeToFilter('is_active', 1)
            ->setOrder('level', 'DESC');

        $category = $collection->getFirstItem();

        return $category->getId() ? $category : null;
    }
}

Since the schema is added with a plugin, you don't need to override any .phtml templates. The schema is injected straight into the existing breadcrumb HTML output.

Step 3: Enable the module

To enable the module, run the following commands:

bin/magento module:enable Vendor_RichSnippets
bin/magento setup:upgrade
bin/magento cache:flush

Add breadcrumb schema in Magento automatically

To add breadcrumb schema in Magento automatically, use the Magento 2 Rich Snippets extension by Magefan. The extension generates BreadcrumbList schema based on your Magento breadcrumbs, reflecting your current store hierarchy. If anything in your catalog changes, it updates your structured data as well. No manual work required.

To enable Magento breadcrumbs snippets:

  1. Go to Stores > Configurations > Magefan Extensions > Rich Snippets.
  2. Scroll down to the Breadcrumbs Snippet feature and enable it by pressing Yes.
enabling magento breadcrumbs snippet

Enabling breadcrumbs snippet by Magento 2 Rich Snippets extension

Then Save the config and flush Magento cache to apply schema markup.

As simple as that. From now on, the Magefan extension automatically generates and updates breadcrumbs schema as your store grows.

How to Check if Your Breadcrumb Schema Works?

To check if your breadcrumb schema is valid, run a live page URL check in Google Rich Results Test and Schema Markup Validator.

Google Rich Results Test checks whether Google can read breadcrumb schema (and potentially show it as a rich result).

magento breadcrumb schema rich result test

Breadcrumb schema test result in Google Rich Results Test

Schema Markup Validator, on the other hand, verifies if your structured data follows the official Schema.org standards.

magento schema markup validator test

Breadcrumb schema test result in Schema Markup Validator

If any errors occur, these tools will highlight them so that you can fix everything before search engines crawl your page.

Once the Magento breadcrumb schema is live across all pages, you can use Google Search Console to check the breadcrumbs performance through the Breadcrumbs report.

breadcrumbs validation in google search console

Breadcrumbs validations in Search Console

If you use Magefan Rich Snippets, the process becomes much easier since it reduces the risk of manual errors. The extension automatically builds and maintains breadcrumb markup.

Besides breadcrumb schema, the extension allows you to add other rich snippets to Magento, including product, FAQ, and organization schema. This way, you can keep structured data across your entire store accurate and up to date without custom development.

FAQs

Do all Magento pages need breadcrumb schema?

collapsible icon
Not all Magento pages need breadcrumb schema. Pages like the homepage, shopping cart, or checkout won't benefit from it, since they don't have a meaningful hierarchical position to display.

Where to put breadcrumb schema in Magento?

collapsible icon
The JSON-LD script is usually added via layout XML (catalog_category_view.xml for category pages and catalog_product_view.xml for product pages) so that it survives future upgrades. If you use an extension like Magefan Rich Snippets for Magento, it typically injects this automatically into page output without manual template edits.

Does changing Magento category URLs require updating breadcrumb schema?

collapsible icon
If you rename categories, change the URL, or move the product to another category, your breadcrumb schema needs to reflect the updated hierarchy. Otherwise, it will show a mismatched or outdated path. Magefan Rich Snippets extension automatically updates the breadcrumbs schema after any category changes.