DEV Community

loading...

Preventing Category URL from the product page in Magento2

Anuradha Fernando
PHP/Magento Cloud developer.
・2 min read

Magento is providing the best tool for managing the product URLs which is the URL Rewrite mechanism. It enables to convert the product URLs to more readable when visitors access the Target URLs.

eg:
Target URL
/catalog/product/view/id/21

Request URL
/mens/this-is-a-nic-url.html

So using both types of URLs will result the same product page in the frontend. Sometimes you might need to prevent accessing one URL type,

eg: if you need to prevent access to the Target URL but allows the Request URL, we can handle that scenario as follows.

I've created a sample module for this.

Directory Structure

Vendor
-Module Name
--etc
--Observer
--registration.php

First Create the module.xml and registration.php

Inside the etc, create a directory frontend and create a file events.xml

events.xml

<?xml version="1.0"?>
<!--
/**
 * Copyright (c)
 */
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
    <event name="controller_action_predispatch_catalog_product_view">
        <observer name="vendor_predispatch" instance="Vendor\Module\Observer\PreDispatch" />
    </event>
</config>
Enter fullscreen mode Exit fullscreen mode

Create a directory Observer in the module root. Create a file inside the Observer directory PreDispatch.php

PreDispatch.php

<?php
/**
 * Copyright (c)
 */

namespace Vendor\Module\Observer;

use Magento\Framework\App\Request\Http;
use Magento\Framework\App\ResponseInterface;
use Magento\Framework\Event\Observer;
use Magento\Framework\Event\ObserverInterface;
use Magento\Framework\UrlInterface;
use Magento\Framework\View\Context;

class PreDispatch implements ObserverInterface
{
    /**
     * Uri value to be checked with
     */
    const NEEDLE = '/catalog/';

    /**
     * @var ResponseInterface
     */
    private $response;

    /**
     * @var Context
     */
    private $context;

    /**
     * @var Http
     */
    private $http;

    /**
     * @var UrlInterface
     */
    private $url;

    /**
     * CatalogCategoryViewPostDispatch constructor.
     *
     * @param ResponseInterface $response
     * @param Context $context
     * @param Http $http
     * @param UrlInterface $url
     */
    public function __construct(
        ResponseInterface $response,
        Context $context,
        Http $http,
        UrlInterface $url
    ) {
        $this->response = $response;
        $this->context = $context;
        $this->http = $http;
        $this->url = $url;
    }

    /**
     * @param Observer $observer
     */
    public function execute(Observer $observer)
    {
        if (substr($this->http->getRequestUri(), 0, 9) === self::NEEDLE) {
            $customerBeforeAuthUrl = $this->url->getUrl('noroute');
            $this->response->setRedirect($customerBeforeAuthUrl)
            ->sendResponse();
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Cheers!

Discussion (0)