Skip to content

Instantly share code, notes, and snippets.

@asheroto
Created October 7, 2023 05:48
Show Gist options
  • Save asheroto/149827e2f6fe731e2d6fac5c5227241f to your computer and use it in GitHub Desktop.
Save asheroto/149827e2f6fe731e2d6fac5c5227241f to your computer and use it in GitHub Desktop.
Easily load and reset Cloudflare Turnstile when an element (div) appears. For example, when success element is shown, reset Turnstile.

Easily load and reset Cloudflare Turnstile when an element (div/span) appears. For example, when success element is shown, reset Cloudflare Turnstile.

The purpose of this script is to handle the situation where you want to reset Cloudflare Turnstile after a contact form was submitted, so that someone could submit the form again without having to reload the page.

Script Functionality

  1. Loads Cloudflare Turnstile dynamically (only import this turnstile.js script in your main HTML) without the need to import it on a separate line
  2. Waits until the triggerWhenVisibleSelector becomes visible
  3. Resets Cloudflare Turnstile so it can be used again

How to use

  1. Change the widgetSelector to the ID (or class) of the container that will hold the Turnstile widget that will by dynamically rendered. In the following example you would use #turnstile-container:
<div id="turnstile-container">
	<!-- When rendered, Turnstile will appear here -->
</div>
  1. Change the siteKey to your site key provided by Cloudflare
  2. Change the triggerWhenVisibleSelector to the query selector of the element that, when becoming visible, should trigger the reset of Turnstile. In the following example you would use .u-form-send-success:
<div class="u-form-send-success">
	Thank you! Your message has been sent.
</div>
  1. Save turnstile.js and place in the appropriate directory
  2. Import turnstile.js in your script before the </body> tag:
<!-- Cloudflare Turnstile -->
<script src="turnstile.js" defer></script>
const script = document.createElement('script');
script.src = 'https://challenges.cloudflare.com/turnstile/v0/api.js?onload=onloadTurnstileCallback';
script.type = 'text/javascript';
script.defer = true;
script.onload = function () {
let widgetSelector = 'CHANGE-ME-TO-WIDGET-ID';
let siteKey = 'CHANGE-ME-TO-SITE-KEY';
let triggerWhenVisibleSelector = 'CHANGE-ME-WHEN-VISIBLE-TRIGGER-TURNSTILE';
window.onloadTurnstileCallback = function () {
turnstile.render(widgetSelector, {
sitekey: siteKey,
callback: turnstileCallback
});
};
window.turnstileCallback = function (id) {
// console.log("Turnstile token:", id);
}
function resetTurnstile() {
try {
console.log("Trying to reset Turnstile with widgetSelector =", widgetSelector);
if (widgetSelector && turnstile && typeof turnstile.reset === "function") {
turnstile.reset(widgetSelector);
console.log("Turnstile reset");
} else {
console.log("Turnstile or reset function is undefined");
}
} catch (e) {
console.error("Error resetting Turnstile:", e);
}
}
$(document).ready(function () {
const observer = new MutationObserver(mutations => {
mutations.forEach(mutation => {
const target = mutation.target;
if ($(target).is(':visible')) {
console.log("Resetting Turnstile");
resetTurnstile();
}
});
});
observer.observe($(triggerWhenVisibleSelector)[0], { attributes: true });
});
};
document.head.appendChild(script);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment