: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
captchaID = turnstile.render(el, {
theme: "' . $captcha_settings['theme'] . '",
turnstileUpdateContainer(el);
wpformsRecaptchaCallback(el);
"timeout-callback": function() {
turnstileUpdateContainer(el);
el.setAttribute("data-recaptcha-id", captchaID);
wpformsDispatchEvent( document, "wpformsRecaptchaLoaded", true );
if ( $captcha_settings['recaptcha_type'] === 'v3' ) {
$data .= /** @lang JavaScript */
'var wpformsRecaptchaV3Execute = function ( callback ) {
grecaptcha.execute( "' . $captcha_settings['site_key'] . '", { action: "wpforms" } ).then( function ( token ) {
Array.prototype.forEach.call( document.getElementsByName( "wpforms[recaptcha]" ), function ( el ) {
if ( typeof callback === "function" ) {
grecaptcha.ready( function () {
wpformsDispatchEvent( document, "wpformsRecaptchaLoaded", true );
} elseif ( $captcha_settings['recaptcha_type'] === 'invisible' ) {
$data .= /** @lang JavaScript */
'var wpformsRecaptchaLoad = wpformsRecaptchaSync( function () {
Array.prototype.forEach.call(document.querySelectorAll(".g-recaptcha"), function (el) {
var recaptchaID = grecaptcha.render(el, {
"callback": function () {
wpformsRecaptchaCallback(el);
"error-callback": function () {
wpformsRecaptchaErrorCallback(el);
el.closest("form").querySelector("button[type=submit]").recaptchaID = recaptchaID;
wpformsDispatchEvent(document, "wpformsRecaptchaLoaded", true);
var wpformsRecaptchaCallback = function (el) {
var $form = el.closest("form");
if (typeof wpforms.formSubmit === "function") {
wpforms.formSubmit($form);
$form.querySelector("button[type=submit]").recaptchaID = false;
var wpformsRecaptchaErrorCallback = function (el) {
var $form = el.closest("form");
$form.querySelector("button[type=submit]").dataset.captchaInvalid = true;
$data .= /** @lang JavaScript */
'var wpformsRecaptchaLoad = function () {
Array.prototype.forEach.call(document.querySelectorAll(".g-recaptcha"), function (el) {
var recaptchaID = grecaptcha.render(el, {
wpformsRecaptchaCallback(el);
el.setAttribute("data-recaptcha-id", recaptchaID);
wpformsDispatchEvent(document, "wpformsRecaptchaLoaded", true);
* Cloudflare Turnstile captcha requires defer attribute.
* @param string $tag HTML for the script tag.
* @param string $handle Handle of script.
* @param string $src Src of script.
public function set_defer_attribute( $tag, $handle, $src ) {
$captcha_settings = wpforms_get_captcha_settings();
if ( $captcha_settings['provider'] !== 'turnstile' ) {
if ( $handle !== 'wpforms-recaptcha' ) {
return str_replace( ' src', ' defer src', $tag );