āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā ā š shadcn/directory/clerk/clerk-docs/guides/development/custom-flows/authentication/bot-sign-up-protection ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā
Clerk provides the ability to add a CAPTCHA widget to your sign-up flows to protect against bot sign-ups. The <SignUp /> component handles this flow out-of-the-box. However, if you're building a custom user interface, this guide will show you how to add the CAPTCHA widget to your custom sign-up flow.
[!WARNING] If you currently have the Invisible CAPTCHA type selected, it's highly recommended to switch to the Smart option, as the Invisible option is deprecated and will be removed in a future update.
To render the CAPTCHA widget in your custom sign-up form, you need to include the <div id="clerk-captcha" /> element by the time you call signUp.create(). This element acts as a placeholder onto which the widget will be rendered.
If this element is not found, the SDK will transparently fall back to an invisible widget in order to avoid breaking your sign-up flow. If this happens, you should see a relevant error in your browser's console.
[!TIP] The invisible widget fallback automatically blocks suspected bot traffic without offering users falsely detected as bots with an opportunity to prove otherwise. Therefore, it's strongly recommended that you ensure the
<div id="clerk-captcha" />element exists in your DOM.
The following example shows how to support the CAPTCHA widget:
<>
<h1>Sign up</h1>
<form onSubmit={handleSubmit}>
<div>
<label htmlFor="email">Enter email address</label>
<input
id="email"
type="email"
name="email"
value={emailAddress}
onChange={(e) => setEmailAddress(e.target.value)}
/>
</div>
<div>
<label htmlFor="password">Enter password</label>
<input
id="password"
type="password"
name="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
/>
</div>
{/* Clerk's CAPTCHA widget */}
<div id="clerk-captcha" />
<button type="submit">Continue</button>
</form>
</>
You can customize the appearance of the CAPTCHA widget by passing data attributes to the <div id="clerk-captcha" /> element. The following attributes are supported:
data-cl-theme: The CAPTCHA widget theme. Can take the following values: 'light', 'dark', 'auto'. Defaults to 'auto'.data-cl-size: The CAPTCHA widget size. Can take the following values: 'normal', 'flexible', 'compact'. Defaults to 'normal'.data-cl-language: The CAPTCHA widget language. Must be either 'auto' (default) to use the language that the visitor has chosen, or language and country code (e.g. 'en-US'). Some languages are supported by Clerk but not by Cloudflare Turnstile, which is used for the CAPTCHA widget. See Cloudflare Turnstile's supported languages.For example, to set the theme to 'dark', the size to 'flexible', and the language to 'es-ES', you would add the following attributes to the <div id="clerk-captcha" /> element:
<div id="clerk-captcha" data-cl-theme="dark" data-cl-size="flexible" data-cl-language="es-ES" />
</Steps>ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā