Follow by Email

Thursday, July 10, 2014

Remove category path from product URL in magento

As great as Magento is there are a number of failings it can have from an search engine optimisation point of view and one of the biggest bugbears our SEO consultants have had with it is the number of different URLs a product can be accessed on.
If product a is in category 1 and two then by default magento will create links to it on the following URLs.
  • www.mystore.com/category-1/product-a.html
  • www.mystore.com/category-2/product-a.html
  • www.mystore.com/product-a.html
This can cause duplicate content issues from a search engine point of view. One solution is ensuring that you have canonical URLs in place so the search engine knows which is the primary URL. Better still is to ensure the same URL is produced for the product each and every time by removing the category part.
The file to edit is /app/code/core/Mage/Catalog/Model/Url.php though i advise rather than editing this directly you create a copy in /app/code/local/Mage/Catalog/Model/Url.php.
Then within function getProductRequestPath (around line 685) amend the following code

/**
     * Prepare product base request path
     */
    /*if ($category->getLevel() > 1) {
        // To ensure, that category has path either from attribute or generated now
        $this->_addCategoryUrlPath($category);
        $categoryUrl = Mage::helper('catalog/category')->getCategoryUrlPath($category->getUrlPath(),
            false, $storeId);
        $requestPath = $categoryUrl . '/' . $urlKey;
    } else {*/
        $requestPath = $urlKey;
    //}

And for good measure also amend the function generatePath to edit around line 831 and comment out this section.

/*if ($category->getLevel() > 1) {
                // To ensure, that category has url path either from attribute or generated now
                $this->_addCategoryUrlPath($category);
                $categoryUrl = Mage::helper('catalog/category')->getCategoryUrlPath($category->getUrlPath(),
                    false, $category->getStoreId());
                return $this->getUnusedPath($category->getStoreId(), $categoryUrl . '/' . $urlKey . $productUrlSuffix,
                    $this->generatePath('id', $product, $category)
                );
            }*/

and around 851 

/*if ($category && $category->getLevel() > 1) {
    return 'catalog/product/view/id/' . $product->getId() . '/category/' . $category->getId();
}*/
 
and around 348
 
/*if ($category->getLevel() > 1) {
            $categoryId = $category->getId();
            $updateKeys = false;
        }*/
 
The next file to edit is /app/code/core/Mage/Catalog/Model/Product/Url.php (again I advise rather than editing this directly you create a copy in /app/code/local) in which we need to ensure the categoryid used for generating the links is always set to null. Edit the function getUrl around line 172 and make the follow amend
 
/* commenting this out and setting the categoryId to null everytime
if (isset($params['_ignore_category'])) {
    unset($params['_ignore_category']);
    $categoryId = null;
} else {
    $categoryId = $product->getCategoryId() && !$product->getDoNotUseCategoryId()
        ? $product->getCategoryId() : null;
}*/
 
$categoryId = NULL;
 
Then hey presto now all the product links in your store should ignore the category path and cut down on canonicalisation issures. I am still in the early days of testing this thus far but have not experienced any problems from it yet.
If you are not comfortable in editing the code yourself then stayed tuned for our all singing all dancing SEO module for magento which will give you greater control over not just this but several other search engine optimisation features of magento.