Better Captcha

Preact

Using better-captcha with Preact

Installation

npm i @better-captcha/preact

Basic Usage

import { ReCaptcha } from "@better-captcha/preact/provider/recaptcha";

export default function Example() {
  return <ReCaptcha sitekey="your-site-key" />;
}

Imperative Handle

Preact uses refs with useRef to access the imperative handle for programmatic control.

import { useRef } from "preact/hooks";
import { ReCaptcha, type ReCaptchaHandle } from "@better-captcha/preact/provider/recaptcha";

export default function Example() {
  const recaptchaRef = useRef<ReCaptchaHandle>(null!);

  return (
    <>
      <ReCaptcha sitekey="6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI" ref={recaptchaRef} />
      <button onClick={() => recaptchaRef.current.execute()}>Execute</button>
      <button onClick={() => recaptchaRef.current.reset()}>Reset</button>
      <button onClick={() => console.log(recaptchaRef.current.getResponse())}>Log response</button>
    </>
  );
}

The handle is available as soon as the widget is rendered. Until then, a safe no-op handle is exposed to maintain type safety.

Lifecycle Callbacks

All captcha components support three lifecycle callbacks for handling different stages of the widget lifecycle.

import { ReCaptcha } from "@better-captcha/preact/provider/recaptcha";

export default function Example() {
  const handleReady = () => {
    console.log("Captcha is ready");
  };

  const handleSolve = (token: string) => {
    console.log("Captcha solved with token:", token);
    // Send token to your backend for verification
  };

  const handleError = (error: Error | string) => {
    console.error("Captcha error:", error);
  };

  return (
    <ReCaptcha 
      sitekey="6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI"
      onReady={handleReady}
      onSolve={handleSolve}
      onError={handleError}
    />
  );
}
CallbackParametersDescription
onReady() => voidCalled when the widget is rendered and ready for interaction
onSolve(token: string) => voidCalled when the challenge is solved with the response token
onError(error: Error | string) => voidCalled when an error occurs during initialization or solving

Manual Rendering

By default, captchas automatically render on mount. For more control, disable auto-rendering and trigger it manually.

import { useRef } from "preact/hooks";
import { ReCaptcha, type ReCaptchaHandle } from "@better-captcha/preact/provider/recaptcha";

export default function Example() {
  const recaptchaRef = useRef<ReCaptchaHandle>(null!);

  return (
    <>
      <ReCaptcha 
        sitekey="6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI" 
        ref={recaptchaRef} 
        autoRender={false} 
      />
      <button onClick={() => recaptchaRef.current.render()}>Show Captcha</button>
    </>
  );
}

Common Props

PropTypeRequiredDescription
sitekeystring✅Your provider's site key
optionsobject❌Provider-specific configuration options
autoRenderboolean❌Whether to render automatically on mount (default: true)
scriptOptionsobject❌Script loading configuration (see Script Options)
onReadyfunction❌Callback when widget is ready
onSolvefunction❌Callback when challenge is solved
onErrorfunction❌Callback when an error occurs

Handle Methods

All providers implement these methods on the handle:

Prop

Type

Available Providers

ProviderImport Path
ReCaptcha@better-captcha/preact/provider/recaptcha
HCaptcha@better-captcha/preact/provider/hcaptcha
Turnstile@better-captcha/preact/provider/turnstile
Friendly Captcha@better-captcha/preact/provider/friendly-captcha
Private Captcha@better-captcha/preact/provider/private-captcha
Captcha Fox@better-captcha/preact/provider/captcha-fox
Prosopo@better-captcha/preact/provider/prosopo
CapWidget@better-captcha/preact/provider/cap-widget
Altcha@better-captcha/preact/provider/altcha
See the Provider Documentation for provider-specific options and configuration.

On this page