Captcha
Captcha
Protect registration, password reset, and custom API routes against bots with Cloudflare Turnstile or Google reCAPTCHA v3.
VitNode provides built-in bot protection. When enabled in your API configuration, gated routes automatically demand and verify a challenge token before handler execution.
Quick start
1. Configure Captcha in API Config
Add the captcha configuration to apps/api/src/vitnode.api.config.ts:
import { buildApiConfig } from "@vitnode/core/vitnode.config"
export const vitNodeApiConfig = buildApiConfig({
captcha: process.env.CLOUDFLARE_TURNSTILE_SECRET_KEY
? {
type: "cloudflare_turnstile",
siteKey: process.env.CLOUDFLARE_TURNSTILE_SITE_KEY,
secretKey: process.env.CLOUDFLARE_TURNSTILE_SECRET_KEY,
}
: undefined,
})Built-in user registration and password recovery routes are protected immediately:

2. Protect Custom API Routes
Enable captcha verification on any custom Hono endpoint with withCaptcha: true:
import { buildRoute } from "@vitnode/core/api/lib/route"
export const createCommentRoute = buildRoute({
pluginId: "blog",
withCaptcha: true,
route: {
method: "post",
path: "/",
responses: { 201: { description: "Comment created" } },
},
handler: async (c) => {
// Execution only reaches here if the captcha token is valid
},
})3. Render the Frontend Widget
Include <Captcha /> in your form and supply the received token to fetcherClient:
import { Captcha } from "@vitnode/core/components/captcha"
import { fetcherClient } from "@vitnode/core/lib/fetcher-client"
export const CommentForm = () => {
const [captchaToken, setCaptchaToken] = React.useState<string>()
const handleSubmit = async () => {
await fetcherClient(commentsModule, {
method: "post",
path: "/",
captchaToken,
body: { text: "Nice article!" },
})
}
return (
<form onSubmit={handleSubmit}>
<textarea />
<Captcha onVerify={setCaptchaToken} />
<button disabled={!captchaToken}>Submit Comment</button>
</form>
)
}Supported Providers
Cloudflare Turnstile
Privacy-friendly visible widget with dummy test keys for local dev
Google reCAPTCHA v3
Invisible background score verification (0.5 default threshold)