Magento Product Page SEO – Ensure Breadcrumbs Always Display

breadcrumbsnavigationproductseo

I.e. if you click on a product link in a Google search for example, when you come to the product page it will show the breadcrumb simply as:

Home / Product name

Which is missing the category structure showing where this product is held.

So there is key navigation links missing from this page that is displayed for the user.

I have the below code that will fix this BUT it doesn't work on any sub stores, and completely breaks them.

/**
 * Preparing layout
 *
 * @return Mage_Catalog_Block_Breadcrumbs
 */
protected function _prepareLayout()
{
if ($breadcrumbsBlock = $this->getLayout()->getBlock('breadcrumbs')) {
    $breadcrumbsBlock->addCrumb('home', array(
        'label'=>Mage::helper('catalog')->__('Home'),
        'title'=>Mage::helper('catalog')->__('Go to Home Page'),
        'link'=>Mage::getBaseUrl()
    ));
    // sometimes magento can't get category associated with a product
    // so the full breadcrumb is not shown
    // this is a hack to fix the issue.
    $current_category   = Mage::registry('current_category');
    $current_product    = Mage::registry('current_product');
    // let's check if magento knows what current category is
    // if it doesn't know, let's feed this info to it's brain :)
    if(!$current_category && $current_product){
        $categories = $current_product->getCategoryCollection()->addAttributeToSelect('name')->setPageSize(1);
        foreach($categories as $category) {
            Mage::unregister('current_category');
            Mage::register('current_category', $category);
        }
    }
    $title = array();
    $path  = Mage::helper('catalog')->getBreadcrumbPath();
    foreach ($path as $name => $breadcrumb) {
        $breadcrumbsBlock->addCrumb($name, $breadcrumb);
        $title[] = $breadcrumb['label'];
    }
    if ($headBlock = $this->getLayout()->getBlock('head')) {
        $headBlock->setTitle(join($this->getTitleSeparator(), array_reverse($title)));
    }
}
return parent::_prepareLayout();
}

Any ideas on a full solution that will work with sub stores? My understanding is there are basic SEO benefits of implementing this on top of the navigational benefit.

Best Answer

I know this is quite old, but I'd like to share my solution anyway as it doesn't override/clone any core files.

  1. In your custom module add the following to your config.xml:

    <config>
        ...
        <frontend>
            <events>
                <catalog_controller_product_init>
                    <observers>
                        <breadcrumb_categorypath_product_init>
                            <type>singleton</type>
                            <class><Your Namespace>_<Your Module>_Model_Observer</class>
                            <method>fullBreadcrumbCategoryPath</method>
                        </breadcrumb_categorypath_product_init>
                    </observers>
                </catalog_controller_product_init>
            </events>
        </frontend>
    </config>
    
  2. Create an Observer.php in /app/code/local/<Your Namespace>/<Your Module>/Model/

  3. Add the following to your Observer.php:

    class <Your Namespace>_<Your Module>_Model_Observer {
        public function fullBreadcrumbCategoryPath(Varien_Event_Observer $observer) {
            $current_product = Mage::registry('current_product');
    
            if( $current_product ) {
                $categories = $current_product->getCategoryCollection()->addAttributeToSelect('name')->setPageSize(1);
                foreach( $categories as $category ) {
                    Mage::unregister('current_category');
                    Mage::register('current_category', $category);
                }
            }
        }
    }
    
  4. You should be good to go.