Let me discuss one interesting problem which I faced with Magento 2.
In my Magento 2 store, I needed to prevent/omit the category path from product URL when accessing any product page. I need to remove the category path from the Product URL when I access any product page.
Magento Admin Configuration to Remove Category Path
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.
Example of Category Path in Product URL
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:
- http://magento2.demo.ubertheme.com/women/tops-women/jackets-women/olivia-1-4-zip-light-jacket.html
- It includes the category path in product URL
- http://magento2.demo.ubertheme.com/olivia-1-4-zip-light-jacket.html
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 first creating an after Plugin on the findOneByData() function of the Magento\UrlRewrite\Model\Storage\AbstractStorage model class.
In order to implement this solution and effectively omit the category path from the product URL, first follow the steps outlined below, which will guide you to access the product page correctly.
- Step 1: Create a custom module under
app/code
directory with two require fileregistration.php
andetc/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 only if the “Use Categories Path for Product URLs” option is set to No in the Magento backend. Additionally, the Magento configuration path for this option is mentioned above for your reference.
- 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
First, enter a product URL with the category path directly in the browser’s address bar. Then, you will notice it redirects automatically to the product URL without the category path.
Final Words
Once you follow these steps carefully and enable the module, you will notice that Magento automatically redirects product URLs without the category path. Therefore, this approach simplifies URL structure, improves SEO, and ensures seamless access for users.
Enjoy Coding. Thank you.
Thank you so much, works perfect!