Migrate from Turnstile to CaptchaLa
Drop-in replacement in under 10 minutes. Keep your forms, drop the Cloudflare dependency, gain challenge fallback and mainland China endpoints.
代码改动长这样
<div class="cf-turnstile" data-sitekey="YOUR_SITE_KEY"></div>
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script><button id="login-btn">Sign in</button>
<script src="https://cdn.captcha-cdn.net/captchala-loader.js"></script>
<script>
loadCaptchala(() => Captchala.init({ appKey: 'YOUR_APP_KEY', action: 'login' })
.onSuccess(res => onToken(res.token))
.bindTo('#login-btn'));
</script>const res = await fetch('https://challenges.cloudflare.com/turnstile/v0/siteverify', {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: new URLSearchParams({
secret: process.env.TURNSTILE_SECRET,
response: req.body['cf-turnstile-response'],
}),
})
const data = await res.json()
if (!data.success) return res.status(400).json({ error: 'bot' })const res = await fetch('https://apiv1.captcha.la/v1/validate', {
method: 'POST',
headers: {
'X-App-Key': process.env.CAPTCHALA_APP_KEY,
'X-App-Secret': process.env.CAPTCHALA_APP_SECRET,
'Content-Type': 'application/json',
},
body: JSON.stringify({ pass_token: req.body['captchala-token'] }),
})
const { data } = await res.json()
if (!data || !data.valid) return res.status(400).json({ error: 'bot' })迁移步骤
- 1
Sign up & grab your App Key + Secret
Create a free CaptchaLa account, add a site, and copy the App Key (public) and App Secret (server-side). No Cloudflare account required.
- 2
Swap the widget tag
Replace cf-turnstile with captchala and data-sitekey with data-app-key. Change the script src to our CDN. The widget shape (a div placeholder + a script tag) is the same.
- 3
Update the hidden field name
Turnstile injects cf-turnstile-response; CaptchaLa injects captchala-token. Most form handlers don't read the field by name, but if yours does, rename the constant in one place.
- 4
Update the server verify call
Change the endpoint to apiv1.captcha.la/v1/validate. We accept JSON (Turnstile takes form-urlencoded), so update Content-Type and body shape. The response still returns a valid flag (data.valid) for your branching code.
- 5
Roll out gradually
Keep Turnstile on most forms, drop CaptchaLa on one low-traffic form first. Watch conversion and challenge rate for a day. Expand once you're satisfied — there's no minimum, no contract.
更快:用插件
WordPress + WooCommerce
If you were using a community Turnstile plugin on WordPress, swap it for our official plugin. Login, registration, comments, WooCommerce checkout, CF7 / Gravity / WPForms — all covered in one install.
View integration →Flarum
Install the CaptchaLa extension via Composer, enable it in admin, and Flarum forms (registration, login, password reset, post replies) all run through CaptchaLa.
View integration →常见问题
Can I keep my Cloudflare CDN and still use CaptchaLa?
Yes. CaptchaLa is independent of any CDN — most of our customers keep Cloudflare for CDN and use CaptchaLa for verification. The two layers don't conflict.
Will my Cloudflare bot detection rules still apply?
Yes — those are Cloudflare WAF / Bot Management features, separate from Turnstile. Removing the Turnstile widget has no effect on your Cloudflare zone configuration.
What if I'm using Turnstile via Cloudflare Workers?
The migration is the same on the Worker side. Replace the Turnstile fetch with the CaptchaLa fetch. We have a snippet in the docs that's compatible with the Workers runtime.