JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 6
  • Score
    100M100P100Q21091F
  • License MIT

A fully customizable CAPTCHA component built for modern web apps

Package Exports

  • @opentech-lab/custom-captcha
  • @opentech-lab/custom-captcha/types

Readme

Custom CAPTCHA – Build Your Own reCAPTCHA-Style Puzzle

A fully customizable CAPTCHA component built for modern web apps for Nextjs(now). Easily plug it into your forms to stop bots, test user knowledge, or filter out unwanted traffic with your own question sets or image-based puzzles. When call this component, it will pupup in the center of screen as a dialog to let user anwser questions. if user got verified, then it will close and record in localstorage(in Nextjs, it can be saved in server side - SSR handle). So no server is need, it is a CAPTCHA for frontend expecially for Nextjs.

Features

  • Protect your website, pages and forms from spam and automation
  • Add your own custom questions (text, image, logic, drag-n-drop)
  • Puzzle types: multiple choice, single choice, text input, image selection
  • Language & culture aware: design puzzles specific to your audience
  • Simple integration with React (other frameworks coming soon)
  • Lightweight & dependency-free (core)

Quick Start Guide

This guide will walk you through setting up the Custom CAPTCHA in a React application.

1. Installation

First, add the package to your project:

npm install @opentech-lab/custom-captcha

2. Usage

Setup questions

import { CaptchaQuestion } from '@opentech-lab/custom-captcha/types';

export const captchaQuestion: CaptchaQuestion[] = [
  {
    id: '1',
    type: 'multiple-choice',
    question: 'What is number?',
    options: ['1', 'abc', '8', 'hello'],
    correctAnswer: ['1', '8'],
  },
  {
    id: '2',
    type: 'single-choice',
    question: 'What is 10 - 4?',
    options: ['5', '6', '7', '8'],
    correctAnswer: ['6'],
  },
  {
    id: '3',
    type: 'text-input',
    question: 'What is the capital of France?',
    correctAnswer: ['Paris'],
  },
  {
    id: '4',
    type: 'images-select',
    question: 'Select all cat images',
    images: [
      { src: '/images/cat1.jpg', answer: true },
      { src: '/images/cat2.jpg', answer: false },
      { src: '/images/cat3.jpg', answer: true },
    ],
    correctAnswer: [], // Not used for images-select, answers are in images array
  },
];

Configuration Options

import { CaptchaConfig } from '@opentech-lab/custom-captcha/types';

export const exampleConfig: CaptchaConfig = {
  questions: captchaQuestion,
  title: "Please complete this verification",
  expiryMinutes: 60,
  storageKey: "custom-captcha-verification",
  questionsToSolve: 2, // Only show 2 random questions from the pool
};

Configuration Properties

Property Type Default Description
questions CaptchaQuestion[] [] Array of questions for the CAPTCHA
title string "Verification Required" Title shown in the CAPTCHA dialog
expiryMinutes number 60 How long verification lasts (minutes)
storageKey string "custom-captcha-verification" Local storage key for verification status
questionsToSolve number 1 Number of questions to solve correctly
zIndex number 99999 Z-index for the CAPTCHA overlay
imageObjectFit string "contain" How images are fitted in image-select questions

Usage Examples

Basic Usage (Single Question)

// Shows 1 random question (default behavior)
<CustomCaptcha question={captchaQuestion} />

Limited Questions (Random Selection)

// Shows only 2 random questions from the pool
const config = {
  questions: captchaQuestion,
  questionsToSolve: 2,
  title: "Quick Verification"
};

<CustomCaptcha config={config} />

Full Configuration Example

// Complete setup with all options
const advancedConfig = {
  questions: captchaQuestion,
  title: "Security Check",
  expiryMinutes: 30,
  storageKey: "my-app-captcha",
  questionsToSolve: 3, // User must solve 3 questions correctly
  zIndex: 999999
};

<CustomCaptcha config={advancedConfig} />

Add in layout

import { CustomCaptcha } from '@opentech-lab/custom-captcha';
import { captchaQuestion, exampleConfig } from '@/config/captchaconfig';
// Types can be imported separately if needed
// import { CaptchaQuestion, CaptchaConfig } from '@opentech-lab/custom-captcha/types';

export default async function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <div>
      {children}
      <CustomCaptcha config={exampleConfig} />
      {/* Alternative: <CustomCaptcha question={captchaQuestion} /> */}
    </div>
  );
}

Key Features

Smart Question System

  • questionsToSolve: Specify how many questions users must solve correctly
  • Users can retry incorrect answers unlimited times (no attempt limits)
  • System presents new random questions until the required number is solved
  • If you have 10 questions but set questionsToSolve: 3, users need to solve any 3 correctly
  • Questions are selected randomly from the pool, avoiding recently solved ones when possible
  • Real-time progress tracking: Shows "Progress: 2 / 3 solved" at top and bottom
  • Button text changes: "Next" → "Complete" on final question

Ethics & Safety

This tool is designed for developers building secure and intentional communities. Use ideological or political filters responsibly. Avoid using CAPTCHAs in ways that could be discriminatory or violate local laws.

License

MIT

Contributing

PRs welcome. If you'd like to contribute new puzzle types, translations, or integrations (Vue, Svelte, etc.), feel free to open an issue or fork the repo.