A lightweight SvelteKit utility that adds CAPTCHA protection to your forms with progressive enhancement. Supports reCAPTCHA v3, hCaptcha, and Cloudflare Turnstile.
enhance
function with CAPTCHA supportnpm install svelte-captcha-enhance
<script>
import { env } from '$env/dynamic/public';
import enhance from 'svelte-captcha-enhance';
</script>
<svelte:head>
<script src="https://www.google.com/recaptcha/api.js?render={env.PUBLIC_RECAPTCHA_SITEKEY}"></script>
</svelte:head>
<form
method="post"
use:enhance={{
type: 'recaptcha',
sitekey: env.PUBLIC_RECAPTCHA_SITEKEY,
action: 'submit',
submit: ({ formData }) => ({ result }) => {
console.log('Form submitted:', result);
}
}}
>
<input type="text" name="name" placeholder="Your name" required />
<button type="submit">Submit</button>
</form>
<script>
import { env } from '$env/dynamic/public';
import enhance from 'svelte-captcha-enhance';
</script>
<svelte:head>
<script src="https://js.hcaptcha.com/1/api.js" async defer></script>
</svelte:head>
<div class="h-captcha" data-sitekey={env.PUBLIC_HCAPTCHA_SITEKEY}></div>
<form
method="post"
use:enhance={{
type: 'hcaptcha',
submit: ({ formData }) => ({ result }) => {
console.log('Form submitted:', result);
}
}}
>
<input type="text" name="name" placeholder="Your name" required />
<button type="submit">Submit</button>
</form>
<script>
import { env } from '$env/dynamic/public';
import enhance from 'svelte-captcha-enhance';
</script>
<svelte:head>
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script>
</svelte:head>
<form
method="post"
use:enhance={{
type: 'turnstile',
sitekey: env.PUBLIC_TURNSTILE_SITEKEY,
submit: ({ formData }) => ({ result }) => {
console.log('Form submitted:', result);
}
}}
>
<input type="text" name="name" placeholder="Your name" required />
<button type="submit">Submit</button>
</form>
Option | Type | Description |
---|---|---|
submit |
SubmitFunction |
Optional callback function (same as SvelteKit's enhance ) |
Option | Type | Required | Description |
---|---|---|---|
type |
'recaptcha' |
â | CAPTCHA provider type |
sitekey |
string |
â | Your reCAPTCHA site key |
action |
string |
â | Action name for reCAPTCHA v3 (default: 'submit') |
Option | Type | Required | Description |
---|---|---|---|
type |
'hcaptcha' |
â | CAPTCHA provider type |
widget |
string |
â | Widget ID (uses first widget if unspecified) |
Option | Type | Required | Description |
---|---|---|---|
type |
'turnstile' |
â | CAPTCHA provider type |
sitekey |
string |
â | Your Turnstile site key |
container |
string | HTMLElement |
â | Container element (uses form if unspecified) |
theme |
'light' | 'dark' | 'auto' |
â | Theme (default: 'auto') |
size |
'normal' | 'invisible' | 'compact' |
â | Size (default: 'normal') |
language |
string | 'auto' |
â | Language (default: 'auto') |
For development or testing purposes:
<form
method="post"
use:enhance={{
type: 'bypass',
submit: ({ formData }) => ({ result }) => {
console.log('Form submitted without CAPTCHA');
}
}}
>
<!-- form content -->
</form>
This library handles the client-side CAPTCHA integration only. You'll need to implement server-side validation yourself using your CAPTCHA provider's verification API. The CAPTCHA responses will be available in your form data as:
g-recaptcha-response
(reCAPTCHA)h-captcha-response
(hCaptcha) cf-turnstile-response
(Turnstile)Check out the examples directory for complete working examples of each CAPTCHA provider.