DEV Community

Joseph Nelson
Joseph Nelson

Posted on

Getting Started with React Simple Captcha: Building CAPTCHA Protection

React Simple Captcha is a lightweight library for creating simple CAPTCHA (Completely Automated Public Turing test to tell Computers and Humans Apart) components in React applications. It provides an easy way to add basic bot protection to forms and user interactions. This guide walks through setting up and creating CAPTCHA protection using React Simple Captcha with React, from installation to a working implementation. This is part 55 of a series on using React Simple Captcha with React.

Prerequisites

Before you begin, make sure you have:

  • Node.js version 14.0 or higher installed
  • npm, yarn, or pnpm package manager
  • A React project (version 16.8 or higher) or create-react-app setup
  • Basic knowledge of React components and forms
  • Familiarity with JavaScript/TypeScript

Installation

Install React Simple Captcha using your preferred package manager:

npm install react-simple-captcha
Enter fullscreen mode Exit fullscreen mode

Or with yarn:

yarn add react-simple-captcha
Enter fullscreen mode Exit fullscreen mode

Or with pnpm:

pnpm add react-simple-captcha
Enter fullscreen mode Exit fullscreen mode

After installation, your package.json should include:

{
  "dependencies": {
    "react-simple-captcha": "^1.0.0",
    "react": "^18.0.0",
    "react-dom": "^18.0.0"
  }
}
Enter fullscreen mode Exit fullscreen mode

Project Setup

React Simple Captcha requires minimal setup. Import the component and you're ready to use it.

First Example / Basic Usage

Let's create a simple CAPTCHA form. Create a new file src/CaptchaExample.jsx:

// src/CaptchaExample.jsx
import React, { useState } from 'react';
import { loadCaptchaEnginge, LoadCanvasTemplate, validateCaptcha } from 'react-simple-captcha';

function CaptchaExample() {
  const [captchaValue, setCaptchaValue] = useState('');
  const [isValid, setIsValid] = useState(null);

  React.useEffect(() => {
    loadCaptchaEnginge(6); // Load CAPTCHA with 6 characters
  }, []);

  const handleSubmit = (e) => {
    e.preventDefault();
    const valid = validateCaptcha(captchaValue);
    setIsValid(valid);
    if (valid) {
      alert('CAPTCHA validated successfully!');
    } else {
      alert('Invalid CAPTCHA. Please try again.');
      loadCaptchaEnginge(6); // Reload CAPTCHA
      setCaptchaValue('');
    }
  };

  return (
    <div style={{ padding: '20px', maxWidth: '400px', margin: '0 auto' }}>
      <h2>CAPTCHA Example</h2>
      <form onSubmit={handleSubmit}>
        <div style={{ marginBottom: '20px' }}>
          <LoadCanvasTemplate />
        </div>
        <div style={{ marginBottom: '20px' }}>
          <label style={{ display: 'block', marginBottom: '5px' }}>
            Enter CAPTCHA:
          </label>
          <input
            type="text"
            value={captchaValue}
            onChange={(e) => setCaptchaValue(e.target.value)}
            style={{
              width: '100%',
              padding: '8px',
              border: '1px solid #ddd',
              borderRadius: '4px',
              boxSizing: 'border-box'
            }}
            placeholder="Enter the text above"
          />
        </div>
        <button
          type="submit"
          style={{
            padding: '10px 20px',
            backgroundColor: '#007bff',
            color: 'white',
            border: 'none',
            borderRadius: '4px',
            cursor: 'pointer',
            width: '100%'
          }}
        >
          Submit
        </button>
        {isValid === false && (
          <p style={{ color: 'red', marginTop: '10px' }}>
            Invalid CAPTCHA. Please try again.
          </p>
        )}
      </form>
    </div>
  );
}

export default CaptchaExample;
Enter fullscreen mode Exit fullscreen mode

Update your App.jsx:

// src/App.jsx
import React from 'react';
import CaptchaExample from './CaptchaExample';
import './App.css';

function App() {
  return (
    <div className="App">
      <CaptchaExample />
    </div>
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

This creates a basic CAPTCHA form that validates user input against the displayed CAPTCHA.

Understanding the Basics

React Simple Captcha provides several key functions:

  • loadCaptchaEnginge: Initializes the CAPTCHA engine with a specified number of characters
  • LoadCanvasTemplate: Renders the CAPTCHA image
  • validateCaptcha: Validates the user's input against the CAPTCHA
  • Simple API: Easy to use with minimal configuration
  • Customizable: Can adjust character count and styling

Key concepts:

  • CAPTCHA Generation: The library generates random text-based CAPTCHAs
  • Validation: User input is compared against the generated CAPTCHA
  • Reload: CAPTCHA can be reloaded if validation fails
  • Canvas Rendering: CAPTCHA is rendered on a canvas element
  • Form Integration: Works seamlessly with React forms

Here's an example with a reload button and custom styling:

// src/AdvancedCaptchaExample.jsx
import React, { useState } from 'react';
import { loadCaptchaEnginge, LoadCanvasTemplate, validateCaptcha } from 'react-simple-captcha';

function AdvancedCaptchaExample() {
  const [captchaValue, setCaptchaValue] = useState('');
  const [isValid, setIsValid] = useState(null);
  const [charCount, setCharCount] = useState(6);

  React.useEffect(() => {
    loadCaptchaEnginge(charCount);
  }, [charCount]);

  const handleReload = () => {
    loadCaptchaEnginge(charCount);
    setCaptchaValue('');
    setIsValid(null);
  };

  const handleSubmit = (e) => {
    e.preventDefault();
    const valid = validateCaptcha(captchaValue);
    setIsValid(valid);
    if (valid) {
      alert('CAPTCHA validated successfully!');
    } else {
      handleReload();
    }
  };

  return (
    <div style={{ padding: '20px', maxWidth: '400px', margin: '0 auto' }}>
      <h2>Advanced CAPTCHA Example</h2>
      <form onSubmit={handleSubmit}>
        <div style={{ marginBottom: '20px' }}>
          <label style={{ display: 'block', marginBottom: '5px' }}>
            Character Count:
          </label>
          <input
            type="number"
            min="4"
            max="8"
            value={charCount}
            onChange={(e) => setCharCount(Number(e.target.value))}
            style={{
              padding: '5px',
              border: '1px solid #ddd',
              borderRadius: '4px',
              width: '100px'
            }}
          />
        </div>
        <div style={{ marginBottom: '20px', border: '1px solid #ddd', padding: '15px', borderRadius: '4px' }}>
          <LoadCanvasTemplate />
          <button
            type="button"
            onClick={handleReload}
            style={{
              marginTop: '10px',
              padding: '5px 10px',
              backgroundColor: '#6c757d',
              color: 'white',
              border: 'none',
              borderRadius: '4px',
              cursor: 'pointer',
              fontSize: '12px'
            }}
          >
            Reload CAPTCHA
          </button>
        </div>
        <div style={{ marginBottom: '20px' }}>
          <label style={{ display: 'block', marginBottom: '5px' }}>
            Enter CAPTCHA:
          </label>
          <input
            type="text"
            value={captchaValue}
            onChange={(e) => setCaptchaValue(e.target.value)}
            style={{
              width: '100%',
              padding: '8px',
              border: isValid === false ? '2px solid red' : '1px solid #ddd',
              borderRadius: '4px',
              boxSizing: 'border-box'
            }}
            placeholder="Enter the text above"
          />
        </div>
        <button
          type="submit"
          style={{
            padding: '10px 20px',
            backgroundColor: '#007bff',
            color: 'white',
            border: 'none',
            borderRadius: '4px',
            cursor: 'pointer',
            width: '100%'
          }}
        >
          Validate CAPTCHA
        </button>
        {isValid === true && (
          <p style={{ color: 'green', marginTop: '10px' }}>
            CAPTCHA validated successfully!
          </p>
        )}
        {isValid === false && (
          <p style={{ color: 'red', marginTop: '10px' }}>
            Invalid CAPTCHA. Please try again.
          </p>
        )}
      </form>
    </div>
  );
}

export default AdvancedCaptchaExample;
Enter fullscreen mode Exit fullscreen mode

Practical Example / Building Something Real

Let's build a complete contact form with CAPTCHA protection:

// src/ContactFormWithCaptcha.jsx
import React, { useState } from 'react';
import { loadCaptchaEnginge, LoadCanvasTemplate, validateCaptcha } from 'react-simple-captcha';

function ContactFormWithCaptcha() {
  const [formData, setFormData] = useState({
    name: '',
    email: '',
    message: ''
  });
  const [captchaValue, setCaptchaValue] = useState('');
  const [isValid, setIsValid] = useState(null);
  const [isSubmitting, setIsSubmitting] = useState(false);

  React.useEffect(() => {
    loadCaptchaEnginge(6);
  }, []);

  const handleInputChange = (e) => {
    const { name, value } = e.target;
    setFormData(prev => ({ ...prev, [name]: value }));
  };

  const handleReloadCaptcha = () => {
    loadCaptchaEnginge(6);
    setCaptchaValue('');
    setIsValid(null);
  };

  const handleSubmit = async (e) => {
    e.preventDefault();
    setIsSubmitting(true);

    // Validate CAPTCHA first
    const captchaValid = validateCaptcha(captchaValue);
    setIsValid(captchaValid);

    if (!captchaValid) {
      setIsSubmitting(false);
      handleReloadCaptcha();
      return;
    }

    // Simulate form submission
    try {
      await new Promise(resolve => setTimeout(resolve, 1000));
      alert('Form submitted successfully!');
      // Reset form
      setFormData({ name: '', email: '', message: '' });
      setCaptchaValue('');
      handleReloadCaptcha();
    } catch (error) {
      alert('Error submitting form. Please try again.');
    } finally {
      setIsSubmitting(false);
    }
  };

  return (
    <div style={{ padding: '20px', maxWidth: '600px', margin: '0 auto' }}>
      <h1>Contact Form with CAPTCHA</h1>
      <form onSubmit={handleSubmit}>
        <div style={{ marginBottom: '16px' }}>
          <label style={{ display: 'block', marginBottom: '4px', fontWeight: '500' }}>
            Name *
          </label>
          <input
            type="text"
            name="name"
            value={formData.name}
            onChange={handleInputChange}
            required
            style={{
              width: '100%',
              padding: '8px',
              border: '1px solid #ddd',
              borderRadius: '4px',
              boxSizing: 'border-box'
            }}
          />
        </div>

        <div style={{ marginBottom: '16px' }}>
          <label style={{ display: 'block', marginBottom: '4px', fontWeight: '500' }}>
            Email *
          </label>
          <input
            type="email"
            name="email"
            value={formData.email}
            onChange={handleInputChange}
            required
            style={{
              width: '100%',
              padding: '8px',
              border: '1px solid #ddd',
              borderRadius: '4px',
              boxSizing: 'border-box'
            }}
          />
        </div>

        <div style={{ marginBottom: '16px' }}>
          <label style={{ display: 'block', marginBottom: '4px', fontWeight: '500' }}>
            Message *
          </label>
          <textarea
            name="message"
            value={formData.message}
            onChange={handleInputChange}
            required
            rows={4}
            style={{
              width: '100%',
              padding: '8px',
              border: '1px solid #ddd',
              borderRadius: '4px',
              boxSizing: 'border-box',
              resize: 'vertical'
            }}
          />
        </div>

        <div style={{ marginBottom: '20px', padding: '15px', border: '1px solid #ddd', borderRadius: '4px', backgroundColor: '#f8f9fa' }}>
          <label style={{ display: 'block', marginBottom: '10px', fontWeight: '500' }}>
            CAPTCHA Verification *
          </label>
          <div style={{ marginBottom: '10px' }}>
            <LoadCanvasTemplate />
          </div>
          <button
            type="button"
            onClick={handleReloadCaptcha}
            style={{
              padding: '5px 10px',
              backgroundColor: '#6c757d',
              color: 'white',
              border: 'none',
              borderRadius: '4px',
              cursor: 'pointer',
              fontSize: '12px',
              marginBottom: '10px'
            }}
          >
            Reload CAPTCHA
          </button>
          <input
            type="text"
            value={captchaValue}
            onChange={(e) => setCaptchaValue(e.target.value)}
            style={{
              width: '100%',
              padding: '8px',
              border: isValid === false ? '2px solid red' : '1px solid #ddd',
              borderRadius: '4px',
              boxSizing: 'border-box'
            }}
            placeholder="Enter CAPTCHA text"
            required
          />
          {isValid === false && (
            <p style={{ color: 'red', marginTop: '5px', fontSize: '14px' }}>
              Invalid CAPTCHA. Please try again.
            </p>
          )}
        </div>

        <button
          type="submit"
          disabled={isSubmitting}
          style={{
            padding: '10px 20px',
            backgroundColor: isSubmitting ? '#6c757d' : '#007bff',
            color: 'white',
            border: 'none',
            borderRadius: '4px',
            cursor: isSubmitting ? 'not-allowed' : 'pointer',
            width: '100%',
            fontSize: '16px'
          }}
        >
          {isSubmitting ? 'Submitting...' : 'Submit Form'}
        </button>
      </form>
    </div>
  );
}

export default ContactFormWithCaptcha;
Enter fullscreen mode Exit fullscreen mode

Update your App.jsx:

// src/App.jsx
import React from 'react';
import ContactFormWithCaptcha from './ContactFormWithCaptcha';
import './App.css';

function App() {
  return (
    <div className="App">
      <ContactFormWithCaptcha />
    </div>
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

This example demonstrates:

  • Contact form with CAPTCHA protection
  • Form validation
  • CAPTCHA validation
  • Reload functionality
  • Error handling
  • User feedback

Common Issues / Troubleshooting

  1. CAPTCHA not displaying: Make sure you've called loadCaptchaEnginge() before rendering LoadCanvasTemplate. This should be done in a useEffect hook.

  2. Validation not working: Ensure you're calling validateCaptcha() with the user's input value. The validation is case-sensitive by default.

  3. CAPTCHA not reloading: Call loadCaptchaEnginge() again to reload the CAPTCHA. Make sure to clear the input value when reloading.

  4. Canvas not rendering: Check that the canvas element has proper dimensions. The library handles this automatically, but ensure there are no CSS conflicts.

  5. Character count: Adjust the number passed to loadCaptchaEnginge() to change the number of characters. Common values are 4-8 characters.

  6. Styling issues: The CAPTCHA is rendered on a canvas, so you can style the container but not the canvas content directly. Use CSS to style the container div.

Next Steps

Now that you have a basic understanding of React Simple Captcha:

  • Learn about advanced CAPTCHA configurations
  • Explore custom styling options
  • Implement CAPTCHA in different form types
  • Add CAPTCHA to login and registration forms
  • Learn about other CAPTCHA libraries (react-google-recaptcha)
  • Check the official repository: https://github.com/masroorejaz/react-simple-captcha
  • Look for part 56 of this series for more advanced topics

Summary

You've successfully set up React Simple Captcha in your React application and created CAPTCHA protection for forms. React Simple Captcha provides a simple solution for adding basic bot protection to your applications with minimal configuration.

SEO Keywords

react-simple-captcha
React CAPTCHA component
react-simple-captcha tutorial
React bot protection
react-simple-captcha installation
React form CAPTCHA
react-simple-captcha example
React captcha validation
react-simple-captcha setup
React security CAPTCHA
react-simple-captcha customization
React captcha library
react-simple-captcha forms
React captcha protection
react-simple-captcha getting started

Top comments (0)