please follow below steps:-
system.xml
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd">
<system>
<tab id="vendor" translate="label" sortOrder="300">
<label>M-Connect Media</label>
</tab>
<section id="module_cpcu" translate="label" type="text" sortOrder="140" showInDefault="1" showInWebsite="1" showInStore="1">
<label>CMS Page Canonical Url</label>
<tab>vendor</tab>
<resource>Vendor_Module::config_cpcu</resource>
<group id="general" translate="label" type="text" sortOrder="2" showInDefault="1" showInWebsite="1" showInStore="1">
<label>General Setting</label>
<field id="active" translate="label" type="select" sortOrder="1" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Enable/Disable</label>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
</field>
<field id="trailing_slash" translate="label" type="select" sortOrder="2" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Remove Trailing slash </label>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
</field>
</group>
</section>
</system>
</config>
Vendor/Module/etc/fronend/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="layout_load_before">
<observer name="seo_layout_load_before" instance="Vendor\Module\Observer\LayoutLoadBefore" />
</event>
</config>
Now in your helper file
Vendor/Module/Helper/Data.php
<?php
namespace Vendor\Module\Helper;
class Data extends \Magento\Framework\App\Helper\AbstractHelper
{
public function getConfig($configPath) {
return $this->scopeConfig->getValue(
$configPath, \Magento\Store\Model\ScopeInterface::SCOPE_STORE
);
}
}
Now create a observer
Vendor/Module/Observer/LayoutLoadBefore.php
<?php
namespace Vendor\Module\Observer;
use Magento\Framework\Event\ObserverInterface;
use Magento\Framework\App\Filesystem\DirectoryList;
class LayoutLoadBefore implements ObserverInterface
{
public function __construct(
\Magento\Framework\View\Page\Config $page,
\Magento\Framework\UrlInterface $urlInterface,
\Mconnectmedia\CmsPageCanonicalUrl\Helper\Data $helper,
\Psr\Log\LoggerInterface $logger
)
{
$this->page = $page;
$this->urlInterface = $urlInterface;
$this->helper = $helper;
$this->logger = $logger;
}
public function execute(\Magento\Framework\Event\Observer $observer)
{
$active=$this->helper->getConfig('module_cpcu/general/active');
if($active){
$action = $observer->getEvent()->getFullActionName();
if ($action == 'cms_page_view' || $action == 'cms_index_index') {
$canonicalUrl= $this->urlInterface->getCurrentUrl();
$trailing_slash=$this->helper->getConfig('module_cpcu/general/trailing_slash');
if($trailing_slash){
$canonicalUrl=rtrim($canonicalUrl,'/');
}
$this->page->addRemotePageAsset(
$canonicalUrl,
'canonical',
['attributes' => ['rel' => 'canonical']]
);
}
return $this;
}
}
}
Vendor/Module/etc/adminhtml/routes.xml
<?xml version="1.0"?>
<!--
/**
* Copyright © 2015 Magento. All rights reserved.
* See COPYING.txt for license details.
*/
-->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd">
<router id="admin">
<route id="module" frontName="module">
<module name="Vendor_Module" before="Magento_Backend" />
</route>
</router>
</config>
Now run setup:upgrade
and static-content:deploy -f
and flush cache
Hope this helps