Slider Captcha
A smooth, interactive sliding puzzle for lightweight human verification and bot prevention.
The Slider Captcha is a modern, user-friendly alternative to traditional "Select all squares with traffic lights" captchas. It uses butter-smooth Framer Motion physics to create an interactive verification step that's easy for humans but difficult for simple automation scripts.
Installation
Run the following command to add the slider-captcha component to your project:
npx shadcn@latest add @flowui/slider-captchaInstall Dependencies
This component requires motion (Framer Motion) and lucide-react.
npm install motion lucide-reactFeatures
- Smooth Draggable: Powered by Framer Motion for natural fluid movement.
- Customizable Appearance: Every part (track, puzzle piece, target) is fully themeable through standard Tailwind classes.
- Randomized Seeding: The puzzle target position is randomized on every mount to prevent static solving.
- Accessibility Focused: Includes a
toleranceprop to adjust difficulty for users with varying motor skills.
Create Component
Copy the implementation from your registry into components/ui/slider-captcha.tsx.
"use client";
import { cn } from "@/lib/utils";
import { Puzzle } from "lucide-react";
import { motion } from "motion/react";
import { useEffect, useRef, useState } from "react";
type SliderCaptchaProps = {
className?: string,
puzzleClassName?: string,
targetClassName?: string,
puzzleIcon?: React.ReactNode;
tolerance?: number,
handleDrag?: () => void,
onSuccess?: () => void,
onFailure?: () => void,
};
export const SliderCaptcha = ({
className,
puzzleClassName,
targetClassName,
puzzleIcon,
tolerance = 5,
handleDrag,
onSuccess,
onFailure,
}: SliderCaptchaProps) => {
// Implementation as provided in the registry...
}Examples
Inline Status Example
Quick Verification
Pendingexport const SliderCaptchaInline = () => {
const [isVerified, setIsVerified] = useState(false);
return (
<SliderCaptcha
puzzleIcon={<Fingerprint className="size-4" />}
onSuccess={() => setIsVerified(true)}
onFailure={() => setIsVerified(false)}
/>
);
}Form Lock Example
export const SliderCaptchaForm = () => {
const [isVerified, setIsVerified] = useState(false);
return (
<form>
<SliderCaptcha
puzzleIcon={<Lock className="size-4" />}
onSuccess={() => setIsVerified(true)}
onFailure={() => setIsVerified(false)}
/>
<Button disabled={!isVerified}>Continue</Button>
</form>
);
}Props
The component is designed to be highly declarative and fits right into your existing Shadcn-styled forms.
| Prop | Type | Default | Description |
|---|---|---|---|
tolerance | number | 5 | Margin of error (in pixels) for successful alignment. |
puzzleIcon | React.ReactNode | <Puzzle /> | The component centered inside the slider. |
onSuccess | () => void | - | Triggered when the puzzle is correctly aligned. |
onFailure | () => void | - | Triggered when the slider is released outside the target. |
className | string | - | Classes for the outer track container. |
puzzleClassName | string | - | Classes for the draggable slider thumb. |
targetClassName | string | - | Classes for the dotted target zone. |
Best Practice: Use the onSuccess callback to unlock form submission buttons or reveal sensitive form segments. This provides a clear, interactive hurdle for bots without degrading the user experience.
References
Inspired by StealthWritter Slider