Skip to content

Client-side rendering

First, you must include the Procaptcha JavaScript resource somewhere in your HTML page. The <script> must be loaded via HTTPS and can be placed anywhere on the page. Inside the <head> tag or immediately after the .procaptcha container are both fine.

<script type="module" src="" async defer></script>

Now, you can either render the Procaptcha widget implicitly or explicitly.

Add an empty DOM container where the Procaptcha widget will be inserted automatically. The container is typically a <div> (but can be any element) and must have class procaptcha and a data-sitekey attribute set to your public site key.

<div class="procaptcha" data-sitekey="your_site_key"></div>

Typically, you’ll want to include the empty .procaptcha container inside an HTML form. When a captcha is successfully solved, a hidden JSON payload will automatically be added to your form that you can then POST to your server for verification. You can retrieve it server side with POST parameter procaptcha-response.

Here’s a full example where Procaptcha is being used to protect a signup form from automated abuse. When the form is submitted, the procaptcha-response token will be included with the email and password POST data after the captcha is solved.

<title>Procaptcha Demo</title>
<script type="module" src="" async defer></script>
<form action="" method="POST">
<input type="text" name="email" placeholder="Email" />
<input type="password" name="password" placeholder="Password" />
<div class="procaptcha" data-sitekey="your_site_key"></div>
<br />
<input type="submit" value="Submit" />

If you prefer to render the widget yourself, you can use the Procaptcha.render() method. The Procaptcha.render() must be called after the procaptcha.bundle.js script has loaded.

The script is loaded in the head of the document and given the id procaptcha-script. A container is created with the id procaptcha-container where the widget will be rendered.

<div id="procaptcha-container"></div>

An onload event is added to the script tag to call the render function when the script has loaded.

// A function that will call the render Procaptcha function when the procaptcha script has loaded
document.getElementById('procaptcha-script').addEventListener('load', function () {
// Define a callback function to be called when the CAPTCHA is verified
function onCaptchaVerified(output) {
console.log('Captcha verified, output: ' + JSON.stringify(output))
// Get the Element using elementId
const captchaContainer = document.getElementById('procaptcha-container')
// Render the CAPTCHA explicitly on a container with id "procaptcha-container"
window.procaptcha.render(captchaContainer, {
siteKey: 'YOUR_SITE_KEY',
theme: 'dark',
callback: onCaptchaVerified,

The Procaptcha.render() function takes an options object as its second argument. The options object can contain the following fields:

siteKeystringThe site key of your application / website. This is required.
callbackstring or functionThe name of the window function, or a function, that will be called when the CAPTCHA is verified.
themestringThe theme of the CAPTCHA widget. The default is light. The other option is dark.
captchaTypestringThe type of CAPTCHA to render. The default is frictionless. Other options are image, pow.
chalexpired-callbackstring or functionThe name of the window function, or a function, that will be called when the CAPTCHA challenge expires.
error-callbackstring or functionThe name of the window function, or a function, that will be called when an error occurs.
close-callbackstring or functionThe name of the window function, or a function, that will be called when the CAPTCHA is closed.
open-callbackstring or functionThe name of the window function, or a function, that will be called when the CAPTCHA is opened.
expired-callbackstring or functionThe name of the window function, or a function, that will be called when the CAPTCHA solution expires.
challenge-valid-lengthnumberThe amount of time, in milliseconds, a successful CAPTCHA challenge is valid for. Defaults to 2 minutes.

The same options can be passed to the implicit rendering method by adding them as data attributes to the .procaptcha. For example, to set the theme to dark, you would add data-theme="dark" to the .procaptcha container.

<div class="procaptcha" data-sitekey="your_site_key" data-theme="dark"></div>

You can choose to implement any of the following types of captcha when rendering the Procaptcha component:

frictionlessThe default CAPTCHA type is frictionless. This type of CAPTCHA is invisible to the user, only requiring them to complete an invisible Proof of Work challenge (pow). Suspected bots are served image captcha challenges (image).
powThe pow CAPTCHA type requires the user to solve a cryptographic puzzle. This puzzle simply requires a small amount of computational work to solve, and slows down bots significantly, making it difficult for them to scrape in high volumes.
imageThe image CAPTCHA type requires the user to solve a simple image CAPTCHA. This is CAPTCHA type most people are familiar with, created by Google reCAPTCHA.

To use the Procaptcha React Component, import Procaptcha, define a config with ProcaptchaConfigSchema, optionally define callbacks, and render via the Procaptcha component. A minimal example would be as follows:

import { Procaptcha } from '@prosopo/procaptcha-react'
import { ProcaptchaConfigSchema } from '@prosopo/types'
const MyApp = () => {
const config = ProcaptchaConfigSchema.parse({
account: {
address: 'YOUR_SITEKEY',
// Other config options, see demos/client-example for more details
return <Procaptcha config={config} />
export default MyApp

Further example usage can be seen in demos/client-example