This is implemented in the Mage2 Module Experius PageNotFound which can be found on Github
For more information see the following commit
I recommend to use Mage2Gen to generate your module for you!
Basic module with Mage2Gen for you!
https://mage2gen.com/load/8cfec17a-a5ff-481e-9f36-2091e0237006
Based on this commit you can implement is as followed:
Add a frontend route - etc/frontend/routes.xml
<?xml version="1.0" ?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
<router id="standard">
<route frontName="vendor_module" id="vendor_module">
<module name="Vendor_Module"/>
</route>
</router>
</config>
Add a frontend event - etc/frontend/events.xml
<?xml version="1.0" ?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
<event name="controller_action_predispatch_cms_noroute_index">
<observer instance="Vendor\Module\Observer\Controller\ActionPredispatch" name="vendor_module_observer_controller_actionpredispatch_controller_action_predispatch"/>
</event>
</config>
Create the Observer and implement this function - Observer/Controller/ActionPredispatch.php
protected function redirect($url)
{
if($url=='410'){
$url = $this->url->getUrl('vendor_module/response/gone', ['_secure' => true]);
}
header("Location: " . $url);
exit();
$this->response->setRedirect($url,$code);
$this->getRequest()->setDispatched(true);
$this->getRequest()->setParam('no_cache', true);
return $this->actionFactory->create('Magento\Framework\App\Action\Redirect');
}
Then add a Controller - Controller/Response/Gone.php
<?php
namespace Vendor\Module\Controller\Response;
class Gone extends \Magento\Framework\App\Action\Action
{
protected $resultPageFactory;
/**
* Constructor
*
* @param \Magento\Framework\App\Action\Context $context
* @param \Magento\Framework\View\Result\PageFactory $resultPageFactory
*/
public function __construct(
\Magento\Framework\App\Action\Context $context,
\Magento\Framework\View\Result\PageFactory $resultPageFactory
) {
$this->resultPageFactory = $resultPageFactory;
parent::__construct($context);
}
/**
* Execute view action
*
* @return \Magento\Framework\Controller\ResultInterface
*/
public function execute()
{
$resultPage = $this->resultPageFactory->create();
$resultPage->setStatusHeader(410, '1.1', 'Gone');
$resultPage->setHeader('Status', '410 Gone');
return $resultPage;
}
}
Add a Block - Block/Response/Gone.php
<?php
namespace Vendor\Module\Block\Response;
class Gone extends \Magento\Framework\View\Element\Template
{
protected function _prepareLayout()
{
$this->pageConfig->addBodyClass('410');
$this->pageConfig->getTitle()->set('410 Gone');
//$this->pageConfig->setKeywords();
//$this->pageConfig->setDescription();
$pageMainTitle = $this->getLayout()->getBlock('page.main.title');
$pageMainTitle->setPageTitle(__('Whoops, our bad...'));
return parent::_prepareLayout();
}
}
Update the frontend with layout xml - view/frontend/layout/vendor_module_response_gone.xml
<?xml version="1.0" ?>
<page layout="1column" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<referenceContainer name="content">
<block class="Vendor\Module\Block\Response\Gone" name="response.gone" template="Vendor_Module::response/gone.phtml"/>
</referenceContainer>
</body>
</page>
And finally add a template - view/frontend/templates/response/gone.phtml
<dl>
<dt><?php echo __('The page you requested was not found, and we have a fine guess why.'); ?></dt>
<dd>
<ul class="disc">
<li><?php echo __('If you typed the URL directly, please make sure the spelling is correct.'); ?></li>
<li><?php echo __('If you clicked on a link to get here, the link is outdated.'); ?></li>
</ul>
</dd>
</dl>
Let me know if you have any questions!