How to Add reCAPTCHA to Magento 2 Custom Form?

Adding reCAPTCHA can protect your website from spam and can also help you differentiate between humans and bots. By using or adding reCAPTCHA to your website or form you can prevent automated software and welcome users with ease.

Add reCAPTCHA to Magento 2 Custom Form:

In this article, we are going to share a 7-step easy solution to add reCAPTCHA to Magento 2 custom form programmatically. Get started with the below-mentioned steps: 

Step 1

Create Addify/HelloWorld/etc/config.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Store:etc/config.xsd">
    <default>
        <customer>
            <captcha>
                <shown_to_logged_in_user>
                    <custom_form>1</custom_form>
                </shown_to_logged_in_user>
                <always_for>
                    <custom_form>1</custom_form>
                </always_for>
            </captcha>
        </customer>
        <captcha translate="label">
            <frontend>
                <areas>
                    <custom_form>
                        <label>Custom Form</label>
                    </custom_form>
                </areas>
            </frontend>
        </captcha>
    </default>
</config>

Step 2

Goto Admin -> Stores -> Configuration -> Customer -> Customer Configuration -> Captcha and configure. You can able to see new forms value Custom Form

Step 3

Create Addify/HelloWorld/view/frontend/layout/yourroutid_index_index.xml

<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" layout="1column" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <head>
        <title>Custom Form</title>
    </head>
    <body>
        <referenceContainer name="content">
            <block class="Addify\HelloWorld\Block\CaptchaForm" name="contactForm" template="Addify_HelloWorld::captchaform.phtml">
                <container name="form.additional.info" label="Form Additional Info">
                    <block class="Magento\Captcha\Block\Captcha" name="captcha" after="-" cacheable="false">
                        <action method="setFormId">
                            <argument name="formId" xsi:type="string">custom_form</argument>
                        </action>
                        <action method="setImgWidth">
                            <argument name="width" xsi:type="string">230</argument>
                        </action>
                        <action method="setImgHeight">
                            <argument name="width" xsi:type="string">50</argument>
                        </action>
                    </block>
                </container>
            </block>
        </referenceContainer>
        <referenceBlock name="head.components">
            <block class="Magento\Framework\View\Element\Js\Components" name="captcha_page_head_components" template="Magento_Captcha::js/components.phtml"/>
        </referenceBlock>
    </body>
</page>

Step 4

Create Addify/HelloWorld/Block/CaptchaForm.php


namespace Addify\HelloWorld\Block;
class CaptchaForm extends \Magento\Framework\View\Element\Template
{
    public function getFormAction()
    {
        return $this->getUrl('yourroute/index/post', ['_secure' => true]);
    }
}

Step 5

Create Addify/HelloWorld/view/frontend/templates/captchaform.phtml

<form class="form contact"
      action="<?php /* @escapeNotVerified */ echo $block->getFormAction(); ?>"
      id="contact-form"
      method="post"
      data-hasrequired="<?php /* @escapeNotVerified */ echo __('* Required Fields') ?>"
      data-mage-init='{"validation":{}}'>
    <fieldset class="fieldset">
        <legend class="legend"><span><?php /* @escapeNotVerified */ echo __('Write Us') ?></span></legend><br />

        <div class="field name required">
            <label class="label" for="name"><span><?php /* @escapeNotVerified */ echo __('Name') ?></span></label>
            <div class="control">
                <input name="name" id="name" title="<?php /* @escapeNotVerified */ echo __('Name') ?>" value="" class="input-text" type="text" data-validate="{required:true}"/>
            </div>
        </div>
        <div class="field email required">
            <label class="label" for="email"><span><?php /* @escapeNotVerified */ echo __('Email') ?></span></label>
            <div class="control">
                <input name="email" id="email" title="<?php /* @escapeNotVerified */ echo __('Email') ?>" value="" class="input-text" type="email" data-validate="{required:true, 'validate-email':true}"/>
            </div>
        </div>
        <?php echo $block->getChildHtml('form.additional.info'); ?>
    </fieldset>
    <div class="actions-toolbar">
        <div class="primary">
            <input type="hidden" name="hideit" id="hideit" value="" />
            <button type="submit" title="<?php /* @escapeNotVerified */ echo __('Submit') ?>" class="action submit primary">
                <span><?php /* @escapeNotVerified */ echo __('Submit') ?></span>
            </button>
        </div>
    </div>
</form>

You can now see the captcha in your form. You must now use an observer to validate your captcha.

Step 6

Create Addify/HelloWorld/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_yourroute_index_post">
        <observer name="captcha_custom_form" instance="Addify\HelloWorld\Observer\CheckCustomFormObserver" />
    </event>
</config>

Step 7

Create Addify/HelloWorld/Observer/CheckCustomFormObserver.php

namespace Addify\HelloWorld\Observer;

use Magento\Framework\Event\ObserverInterface;
use Magento\Framework\App\Request\DataPersistorInterface;
use Magento\Framework\App\ObjectManager;
use Magento\Captcha\Observer\CaptchaStringResolver;

class CheckCustomFormObserver implements ObserverInterface
{
    /**
    * @var \Magento\Captcha\Helper\Data
    */
    protected $_helper;

    /**
    * @var \Magento\Framework\App\ActionFlag
    */
    protected $_actionFlag;

    /**
    * @var \Magento\Framework\Message\ManagerInterface
    */
    protected $messageManager;

    /**
    * @var \Magento\Framework\App\Response\RedirectInterface
    */
    protected $redirect;

    /**
    * @var CaptchaStringResolver
    */
    protected $captchaStringResolver;

    /**
    * @var DataPersistorInterface
    */
    private $dataPersistor;

    /**
    * @param \Magento\Captcha\Helper\Data $helper
    * @param \Magento\Framework\App\ActionFlag $actionFlag
    * @param \Magento\Framework\Message\ManagerInterface $messageManager
    * @param \Magento\Framework\App\Response\RedirectInterface $redirect
    * @param CaptchaStringResolver $captchaStringResolver
    */
    public function __construct(
        \Magento\Captcha\Helper\Data $helper,
        \Magento\Framework\App\ActionFlag $actionFlag,
        \Magento\Framework\Message\ManagerInterface $messageManager,
        \Magento\Framework\App\Response\RedirectInterface $redirect,
        CaptchaStringResolver $captchaStringResolver
    ) {
        $this->_helper = $helper;
        $this->_actionFlag = $actionFlag;
        $this->messageManager = $messageManager;
        $this->redirect = $redirect;
        $this->captchaStringResolver = $captchaStringResolver;
    }

    /**
    * Check CAPTCHA on Custom Form
    *
    * @param \Magento\Framework\Event\Observer $observer
    * @return void
    */
    public function execute(\Magento\Framework\Event\Observer $observer)
    {
        $formId = 'custom_form';
        $captcha = $this->_helper->getCaptcha($formId);
        if ($captcha->isRequired()) {
            /** @var \Magento\Framework\App\Action\Action $controller */
            $controller = $observer->getControllerAction();
            if (!$captcha->isCorrect($this->captchaStringResolver->resolve($controller->getRequest(), $formId))) {
                $this->messageManager->addError(__('Incorrect CAPTCHA.'));
                $this->getDataPersistor()->set($formId, $controller->getRequest()->getPostValue());
                $this->_actionFlag->set('', \Magento\Framework\App\Action\Action::FLAG_NO_DISPATCH, true);
                $this->redirect->redirect($controller->getResponse(), 'yourroute/index/index');
            }
        }
    }

    /**
    * Get Data Persistor
    *
    * @return DataPersistorInterface
    */
    private function getDataPersistor()
    {
        if ($this->dataPersistor === null) {
            $this->dataPersistor = ObjectManager::getInstance()
                ->get(DataPersistorInterface::class);
        }

        return $this->dataPersistor;
    }
}

After following the above mentioned steps your captcha would be added and verified at your site. Now you are good to go with it!

Subscribe to Our Updates and Newsletters