Turnstile server side validation questions

Hi and a happy new year :slight_smile:

I would like to use Cloudflare Turnstile for my contact form.

The widget is already loading successfully.

However, the server side validation does not work.

I have the following in the head:

<script src="https://code.jquery.com/jquery-3.7.1.js"></script>
	<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.19.0/jquery.validate.js"></script>
	<script src="assets/js/jquery.validate.min.js"></script>
	<script src="assets/js/messages_de.js"></script>
	<script src="https://challenges.cloudflare.com/turnstile/v0/api.js?onload=onloadTurnstileCallback" defer></script>

I have the following in the form

<div class='cf-turnstile' data-theme='light' data-sitekey='DELETE'></div>


								function _turnstileCb() {
								    console.debug('_turnstileCb called');

								    turnstile.render('#myWidget', {
								      sitekey: 'DELETE',
								      theme: 'dark',


then I created the index.js with the following code:

import explicitRenderHtml from './explicit.html';
import implicitRenderHtml from './implicit.html';

// This is the demo secret key. In prod, we recommend you store
// your secret key(s) safely.

async function handlePost(request) {
    const body = await request.formData();
    // Turnstile injects a token in "cf-turnstile-response".
    const token = body.get('cf-turnstile-response');
    const ip = request.headers.get('CF-Connecting-IP');

    // Validate the token by calling the "/siteverify" API.
    let formData = new FormData();
    formData.append('secret', SECRET_KEY);
    formData.append('response', token);
    formData.append('remoteip', ip);

    const result = await fetch('https://challenges.cloudflare.com/turnstile/v0/siteverify', {
        body: formData,
        method: 'POST',

    const outcome = await result.json();
    if (!outcome.success) {
        return new Response('The provided Turnstile token was not valid! \n' + JSON.stringify(outcome));
    // The Turnstile token was successfuly validated. Proceed with your application logic.
    // Validate login, redirect user, etc.
    // For this demo, we just echo the "/siteverify" response:
    return new Response('Turnstile token successfuly validated. \n' + JSON.stringify(outcome));

export default {
    async fetch(request) {
        if (request.method === 'POST') {
            return await handlePost(request);

        const url = new URL(request.url);
        let body = implicitRenderHtml;
        if (url.pathname === '/explicit') {
            body = explicitRenderHtml;

        return new Response(body, {
            headers: {
                'Content-Type': 'text/html',

i would like the submit button to be activated after successful validation. without successful validation, the button should remain deactivated.

What am I doing wrong?

Okay, I have now understood that I have to adapt the index.mjs with the secret key and then specify it in package.json. Is that correct?

now I have used the testkeys to test which block the validation. and with the site and secret key the contact form is sent.

What could be the problem?