How to prevent/omit category path from product URL to access the product page?

Let me discuss one interesting problem which I faced with Magento 2.

In Magento 2 Store, I’ve faced an issue with the product URL to access the product page. I need to remove the category path from the Product URL when I access any product page.

I found one admin configuration in Magento Admin at the below path to remove the category path from the product URL.

Path: Admin > STORES > Settings > Configuration > CATALOG > Catalog > Search Engine Optimization

  • Set “Use Categories Path for Product URLs” option to No.
  • After update this configuration, please clean config and full_page cache types and check the product URL.

Now, You can see the category path is removed when you access the product page from the product listing page.

But still, I can access the product page using the product URL with the category path.

For example,
Let’s take an example of the Magento Sample Data’s product name with “Olivia 1/4 Zip Light Jacket”

You can access the product detail page with below URLs by directly entering in the Address Bar of the browser:

Here, I need to prevent the product page access when the URL includes the category path.

So As a solution, I decided If I got the category path in product URL I’ll redirect it to the product URL without category path.

I’ve achieved this solution by creating an after Plugin on findOneByData() function of the Magento\UrlRewrite\Model\Storage\AbstractStorage model class.

Please follow the below steps to implement this solution to omit the category path from the product URL to access the product page.

Step 1: Create a custom module under app/code directory with two require file registration.php and etc/module.xml.

File Path: /app/code/Aureatelabs/DemoModule/registration.php

  • Where Aureatelabs is a vendor name and DemoModule is a module name.
<?php
/**
 * DemoModule
 *
 * Do not edit or add to this file if you wish to upgrade to newer versions in the future.
 * If you wish to customize this module for your needs.
 *
 * @category   DemoModule
 * @package    Aureatelabs_DemoModule
 * @license    http://www.gnu.org/licenses/gpl-3.0.html
 */

\Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::MODULE,
    'Aureatelabs_DemoModule',
    __DIR__
);

File Path: /app/code/Aureatelabs/DemoModule/etc/module.xml

<?xml version="1.0" ?>
<!--
/**
 * DemoModule
 *
 * Do not edit or add to this file if you wish to upgrade to newer versions in the future.
 * If you wish to customize this module for your needs.
 *
 * @category   DemoModule
 * @package    Aureatelabs_DemoModule
 * @license    http://www.gnu.org/licenses/gpl-3.0.html
 */
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
		xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
	<module name="Aureatelabs_DemoModule" setup_version="1.0.0">
	  <sequence>
            <module name="Magento_Catalog"/>
            <module name="Magento_UrlRewrite"/>
        </sequence>
	</module>
</config>

Step 2: Create a di.xml file under etc directory to define a plugin.

File Path: /app/code/Aureatelabs/DemoModule/etc/di.xml

<?xml version="1.0" ?>
<!--
/**
 * DemoModule
 *
 * Do not edit or add to this file if you wish to upgrade to newer versions in the future.
 * If you wish to customize this module for your needs.
 *
 * @category   DemoModule
 * @package    Aureatelabs_DemoModule
 * @license    http://www.gnu.org/licenses/gpl-3.0.html
 */
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\UrlRewrite\Model\Storage\AbstractStorage">
        <plugin disabled="false" name="Plugin_Magento_Checkout_Block_Onepage" sortOrder="10" type="Aureatelabs\DemoModule\Plugin\FindOneByData"/>
    </type>
</config>

Step 3: Create a plugin class under Plugin directory.

File Path: /app/code/Aureatelabs/DemoModule/Plugin/FindOneByData.php

<?php

namespace Aureatelabs\DemoModule\Plugin;

use Magento\Framework\App\Config\ScopeConfigInterface;

/**
 * Class FindOneByData
 * @package Aureatelabs\DemoModule\Plugin
 */
class FindOneByData
{
    /**
     * @var ScopeConfigInterface
     */
    protected $scopeConfig;

    /**
     * FindOneByData constructor.
     * @param ScopeConfigInterface $scopeConfig
     */
    public function __construct(
        ScopeConfigInterface $scopeConfig
    ) {
        $this->scopeConfig = $scopeConfig;
    }

    /**
     * @param \Magento\UrlRewrite\Model\Storage\AbstractStorage $subject
     * @param $result
     * @param array $data
     * @return mixed
     */
    public function afterFindOneByData(
        \Magento\UrlRewrite\Model\Storage\AbstractStorage $subject,
        $result,
        array $data
    ) {
        if(!empty($result) && !(bool)$this->scopeConfig->getValue('catalog/seo/product_use_categories')
            && $result->getEntityType() == 'product'
            && (strpos(trim($result->getRequestPath(), '/'), '/') !== false)
        ) {
            $requestPathArr = explode('/', $result->getRequestPath());
            if (count($requestPathArr) > 1) {
                $newRequestPath = end($requestPathArr);
                $result->setTargetPath($newRequestPath);
                $result->setRedirectType(301);
            }
        }
        return $result;
    }
}

This solution will work if the “Use Categories Path for Product URLs” option is set to No from the Magento backend. The Magento configuration path for this option is mentioned above.

Step 4: Please enabled and install the module using the below commands.

php bin/magento module:enable Aureatelabs_DemoModule
php bin/magento setup:upgrade
php bin/magento setup:di:compile

Please verify module functionality by entering product URL with category path directly in the address bar of the browser, it will redirect to the product URL without category path.

Enjoy Coding.

Thank you.

  • Share :