How to change Google reCAPTCHA (v2) theme dynamically?

306 Views Asked by At

I'm working on a Bootstrap website that has light and dark mode, functioning through JavaScript. And I've integrated Google reCAPTCHA (v2) (I'm not a robot) into my project successfully.

But I want to be able to change reCAPTCHA theme dynamically through the theme toggle switch. As the documentation has an attribute data-theme which we can set value to dark or light.

The main div of reCAPTCHA container through which the theme could be toggled by changing class (rc-anchor-light / rc-anchor-dark) is located inside an iframe.

I tried by adding and removing classes (rc-anchor-light / rc-anchor-dark) from the theme switch JavaScript function to change the reCAPTCHA theme dynamically, but it's not working and I'm not able to figure out why.

1

There are 1 best solutions below

0
Rajesh On

While reCAPTCHA v2 doesn't natively support dynamic theme switching, here's a workaround using multiple reCAPTCHA containers and JavaScript:

HTML structure for two reCAPTCHA containers with different themes

<div class="rg-recaptcha border rounded hide" id="grecaptchaLight" data-callback="recaptchaVe" data-expired-callback="recaptchaEx" data-theme="light"></div>
<div class="rg-recaptcha border rounded hide" id="grecaptchaDark"  data-callback="recaptchaVe" data-expired-callback="recaptchaEx" data-theme="dark"></div>

JavaScript:

// Function to determine the preferred theme (light or dark)

function getPreferredThemeFunction() {
    // Implement your logic to determine the preferred theme here
    // This function should return 'light' or 'dark'
}

// Variable to store the preferred theme
var preferredTheme = getPreferredThemeFunction();

// Variables to store the reCAPTCHA widget IDs
var grecaptchaDarkWD, grecaptchaLightWD;

// Variable to track whether reCAPTCHA has been rendered
var gCapthaRendered = false;

// Callback function triggered when reCAPTCHA is loaded
var onloadCallback = function () {
    // Render reCAPTCHA widgets with dark and light themes
    grecaptchaDarkWD = grecaptcha.render('grecaptchaDark', {
        'sitekey': '1234567890',
        'theme': 'dark'
    });

    grecaptchaLightWD = grecaptcha.render('grecaptchaLight', {
        'sitekey': '1234567890',
        'theme': 'light'
    });

    // Mark reCAPTCHA as rendered
    gCapthaRendered = true;

    // If a preferred theme is set, switch to it
    if (preferredTheme) {
        changeReCaptcha(preferredTheme);
    }
};

// Function to dynamically change the reCAPTCHA theme
function changeReCaptcha(theme = 'light') {
    if (gCapthaRendered) {
        // Reset and hide the inactive reCAPTCHA container
        if (theme == 'dark') {
            document.getElementById('grecaptchaLight').innerHTML = "";
            grecaptcha.reset(grecaptchaDarkWD);
            document.getElementById('grecaptchaLight').classList.add("hide");
            document.getElementById('grecaptchaDark').classList.remove("hide");
        } else if (theme == 'light') {
            document.getElementById('grecaptchaDark').innerHTML = "";
            grecaptcha.reset(grecaptchaLightWD);
            document.getElementById('grecaptchaDark').classList.add("hide");
            document.getElementById('grecaptchaLight').classList.remove("hide");
        }
    }
}