<?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">
        <observer name="GeoIPRedirect" instance="Namespace\Modulename\Observer\GeoIPRedirect" />



namespace Namespace\Modulename\Observer;

use Magento\Framework\Event\Observer;
use Magento\Framework\Event\ObserverInterface;
use Magento\Framework\ObjectManagerInterface;
use Magento\Framework\HTTP\Client\Curl;
use Magento\Framework\UrlInterface;
use Namespace\Modulename\Helper\Data;

class GeoIPRedirect implements ObserverInterface {

    protected $objectManager;
    protected $curl;
    protected $url;
    protected $helper;

    public function __construct(ObjectManagerInterface $objectManager, Curl $curl, UrlInterface $url, Data $helper)

        $this->objectManager = $objectManager;
        $this->curl = $curl;
        $this->url = $url;
        $this->helper = $helper;


    public function getVisitorIP() {       
        $remoteAddress = $this->objectManager->create('Magento\Framework\HTTP\PhpEnvironment\RemoteAddress');
        return $remoteAddress->getRemoteAddress();

    public function execute(Observer $observer) 

        //fetch config
        $visitorIP = $this->getVisitorIP();
        $redirectUrl = $this->url->getUrl('cms-page');
        $serviceURI = "http://somegeoipurl";

        //set curl options
        $this->curl->addHeader("Content-Type", "application/json");

        //fetch json response and decode
        $response = json_decode($this->curl->getBody(), true);

        $stateCode = 'CA';

        if($stateCode == 'CA'){

        return $this;


When above code is executed, the site shows white screen and do not redirect to CMS page.

  1. How do I redirect user to CMS page based on IP using observer i.e. when user access www.site.com redirect to www.site.com/cms-page?
  2. How do I prevent site going into loop if redirected?

1 Answer 1


You need to create plugin for check on every request

create di.xml file in your custom module

<?xml version="1.0"?>

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../../../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">

    <type name="Magento\Framework\App\FrontControllerInterface">
        <plugin name="autoredirect_plugin"

create file Modulename\VendorName\Plugin\AutoRedirect.php add below code.


namespace Modulename\VendorName\Plugin;

use \Magento\Framework\Controller\ResultFactory;
use \Magento\Framework\UrlInterface;
use \Magento\Framework\App\FrontControllerInterface;
use \Magento\Framework\App\RequestInterface;

class AutoRedirect

    protected $logger;

    protected $remoteAddress;

    protected $_curl;

    protected $_resultFactory;

    public function __construct(
    \Psr\Log\LoggerInterface $logger, 
    \Magento\Framework\HTTP\PhpEnvironment\RemoteAddress $remoteAddress,
    ResultFactory $resultFactory,
    UrlInterface    $urlInterface,
    \Magento\Framework\HTTP\Client\Curl $curl) {
        $this->logger = $logger;
        $this->_curl = $curl;
        $this->remoteAddress = $remoteAddress;
        $this->_resultFactory = $resultFactory;
        $this->urlInterface  = $urlInterface;

   public function aroundDispatch(
        FrontControllerInterface $subject,
        callable $proceed,
        RequestInterface $request
    ) {

        $visitorIp = $this->getVisitorIp();
        $url = "freegeoip.net/json/".$visitorIp;
        $response = json_decode($this->_curl->getBody(), true);
        $countryName = $response['country_name'];
        $stateName = $response['region_name'];

        //if any user browse this url than only they get redirect
        $redirectUrl = 'xyz.com';

        // urls array
        $match_urls = array(

        $url = $this->urlInterface->getCurrentUrl();    

        if(in_array($url, $match_urls)) {
            //set any condition as per your requirement
            if($countryName == "CA"){
                $resultRedirect = $this->_resultFactory->create(ResultFactory::TYPE_REDIRECT);
                $resultRedirect->setUrl('your redirect url here');
                return $resultRedirect;     
            } else {
                $resultRedirect = $this->_resultFactory->create(ResultFactory::TYPE_REDIRECT);
                $resultRedirect->setUrl('your other redirect url here');
                return $resultRedirect;
        } else {
           return $proceed($request);

    function getVisitorIp() {
        return $this->remoteAddress->getRemoteAddress();

Note: Make sure you have unique url from which url clients redirect to your specific url. Both should not be same otherwise it will go in infinite loop.


For this why we need to match_urls?

We need match url array because we don't know which url user type. if they can type xyz.com, www.xyz.com, xyz.com .. etc.

  • 1. Why we can not use observer pattern here. And if using observer why the redirection was not working? 2. The method aroundDispatch takes which even or action to redirect user? 3. If user is in CA, and access www.site.net, it will be redirected to www.site.net/cms-page. For this why we need to match_urls? 4. To redirect user to CMS page, if outside CA, the above code throws exception. The page isn’t redirecting properly i.e. going into loop 5. The code also redirects to custome page when you access Magento admin which should not be the case Commented Aug 13, 2018 at 19:14
  • I have not tried with observer. Given way is standard way. AroundDispatch event is of Magento\Framework\App\FrontControllerInterface . Commented Aug 14, 2018 at 16:54
  • Magento admin url is not same so in this case it should not redirect. Updated code please check Commented Aug 14, 2018 at 16:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.