CAPTCHA
Bot protection with Cloudflare Turnstile, Google reCAPTCHA, or hCaptcha
Overview
Form.Captcha adds bot protection to forms. Supports three providers: Cloudflare Turnstile (recommended, free), Google reCAPTCHA, and hCaptcha.
Setup
Configure CAPTCHA once in createForm:
const AppForm = createForm({
captcha: {
provider: 'turnstile',
siteKey: process.env.NEXT_PUBLIC_TURNSTILE_SITE_KEY!,
theme: 'auto',
},
})Usage in Form
<AppForm onSubmit={handleSubmit}>
<AppForm.Field.String name="email" label="Email" />
<AppForm.Field.Textarea name="message" label="Message" />
<AppForm.Captcha />
<AppForm.Button.Submit>Send</AppForm.Button.Submit>
</AppForm>The CAPTCHA token is automatically included in the form data as __captchaToken.
Server Verification
import { verifyCaptcha } from '@letar/forms/captcha'
export async function submitAction(data: FormData) {
const token = data.__captchaToken
const result = await verifyCaptcha(token, {
provider: 'turnstile',
secretKey: process.env.TURNSTILE_SECRET_KEY!,
})
if (!result.success) {
throw new Error('CAPTCHA verification failed')
}
// Process form...
}Providers
| Provider | Free | Invisible | Notes |
|---|---|---|---|
| Turnstile | Yes | Yes | Recommended, privacy-friendly |
| reCAPTCHA | Partial | v3 only | Google, most popular |
| hCaptcha | Partial | Yes | Privacy alternative to reCAPTCHA |
Props
| Prop | Type | Default | Description |
|---|---|---|---|
provider | 'turnstile' | 'recaptcha' | 'hcaptcha' | from createForm | Override provider |
siteKey | string | from createForm | Override siteKey |
theme | 'auto' | 'light' | 'dark' | 'auto' | Widget theme |
size | 'normal' | 'compact' | 'invisible' | 'normal' | Widget size |
language | string | — | Language code (ISO 639-1) |
onSuccess | (token: string) => void | — | Success callback |
onError | (error) => void | — | Error callback |
onExpire | () => void | — | Token expiry callback |
Live Example
Try the interactive example on forms-example.letar.best.