Magento2 Breadcrumbs Disappeared After Upgrading to 2.2.4 – How to Fix

breadcrumbsmagento2.2.4

I upgraded Magento to 2.2.4 & now I don't have breadcrumbs on product pages.
They show up on other pages but not on products.
I checked the source & noticed that there is a div with the 'breadcrumbs' class & some json params, but it's empty (no errors on console).

Any idea?


UPDATE:
I found out that for a reason I can't explain , Magento started building the breadcrumbs of the product pages based on the top-menu navigation using JS & since in my case I changed the menu & used different CSS selectors, it stopped working.
I believe that now I'll be able to fix this, but I can't see any good reason for them to do that, it's way too fragile…


My Temporary Workaround (If it helps someone…):

1. Build a module & add a block that extends \Magento\Theme\Block\Html\Breadcrumbs in order to add the method getCrumbs() *No need for di.xml

namespace Vendor\Module\Block\Html;

class Breadcrumbs extends \Magento\Theme\Block\Html\Breadcrumbs
{
    public function getCrumbs()
    {
        return $this->_crumbs;
    }

    public function getBaseUrl()
    {
        return $this->_storeManager->getStore()->getBaseUrl();
    }
}

2. Override the breadcrumbs template on product page (app/design/frontend/Vendor/Theme/Magento_Catalog/templates/product/breadcrumbs.phtml)

<?php
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$catalogData = $objectManager->create('Magento\Catalog\Helper\Data');
$crumbs = false;
if ($breadcrumbsBlock = $objectManager->create('Vendor\Module\Block\Html\Breadcrumbs')) {
    $breadcrumbsBlock->addCrumb(
        'home',
        [
            'label' => __('Home'),
            'title' => __('Go to Home Page'),
            'link' => $breadcrumbsBlock->getBaseUrl()
        ]
    );
    $path = $catalogData->getBreadcrumbPath();
    foreach ((array)$path as $name => $breadcrumb) {
        $breadcrumbsBlock->addCrumb($name, $breadcrumb);
    }
    $crumbs = $breadcrumbsBlock->getCrumbs();
}
?>
<?php if ($crumbs && is_array($crumbs)) : ?>
    <div class="breadcrumbs">
        <ul class="items">
            <?php foreach ($crumbs as $crumbName => $crumbInfo) : ?>
                <li class="item <?= /* @escapeNotVerified */ $crumbName ?>">
                <?php if ($crumbInfo['link']) : ?>
                    <a href="<?= /* @escapeNotVerified */ $crumbInfo['link'] ?>" title="<?= $block->escapeHtml($crumbInfo['title']) ?>"><?= $block->escapeHtml($crumbInfo['label']) ?></a>
                <?php elseif ($crumbInfo['last']) : ?>
                    <strong><?= $block->escapeHtml($crumbInfo['label']) ?></strong>
                <?php else: ?>
                    <?= $block->escapeHtml($crumbInfo['label']) ?>
                <?php endif; ?>
                </li>
            <?php endforeach; ?>
        </ul>
    </div>
<?php endif; ?>

Best Answer

I found the same problem and did it little bit easier and without ObjectManager. I found out the way how it's done with categories and used that. In catalog_product_view.xml, I rewrite template back to Magento_Theme's one:

<referenceBlock name="breadcrumbs" template="Magento_Theme::html/breadcrumbs.phtml" />

Then I wrote small plugin:

namespace Vendor\Module\Plugin\Catalog\Block\Product;

class View
{

    /**
     * Add Breadcrumbs Block
     *
     * @param \Magento\Catalog\Block\Product\View $subject
     * @param $result
     * @return mixed
     * @throws \Magento\Framework\Exception\LocalizedException
     */
    public function afterSetLayout(\Magento\Catalog\Block\Product\View $subject, $result) {
        $subject->getLayout()->createBlock(\Magento\Catalog\Block\Breadcrumbs::class);

        return $result;
    }
}

Finally, di.xml:

<type name="Magento\Catalog\Block\Product\View">
    <plugin name="add_catalog_breadcrumb_block" type="Vendor\Module\Plugin\Catalog\Block\Product\View" />
</type>

Two problems have been fixed: missing breadcrumbs and missing page title (in head section) in the product page.