Smart bot sign-up protection


The simplest way to take advantage of Bot Protection for your Sign ups is by using our all-in-one <SignUp /> component. This page describes how to implement Bot Protection if you are rebuilding your Sign Up view entirely from scratch using Clerk.

If you have enabled the Smart Bot Protection widget under User & Authentication > Attack Protection > Bot sign-up protection in Dashboard, it's required to include a specific element in your DOM, to enable rendering of the widget.

Specifically, there should be a <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 the 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.

The Invisible widget is more prone to false positives, therefore we strongly recommend that you fix this error by ensuring the <div id="clerk-captcha" /> element exists in your DOM.


import { useState } from "react";
import { useSignUp } from "@clerk/nextjs";
export default function SignUpForm() {
  const { isLoaded, signUp, setActive } = useSignUp();
  const [emailAddress, setEmailAddress] = useState("");
  const [password, setPassword] = useState("");

  const handleSubmit = async (e) => {
    try {
      await signUp.create({
    } catch (err: any) {
      console.error('sign-up error');
  return (
                <label htmlFor="email">Email</label>
                <input onChange={(e) => setEmailAddress(} id="email" name="email" type="email" />
                <label htmlFor="password">Password</label>
                <input onChange={(e) => setPassword(} id="password" name="password" type="password" />

            {/* CAPTCHA Widget */}
            <div id="clerk-captcha"></div>

            <button onClick={handleSubmit}>Sign up</button>


What did you think of this content?