Skip to content
Myra EU CAPTCHA Online Help Updated · 25 Aug 2026

React

The @myrasec/eu-captcha package supplies the EuCaptcha component. The component renders the widget in the form and gives the token to your source code.

Requirements

The following requirements must be met:

Requirement Value
React From version 18
Sitekey Public sitekey from the Details view
Server side Endpoint that verifies the token

Install the package

Install the package:

npm i @myrasec/eu-captcha

Embed the component

Embed the component in the form to protect:

import { EuCaptcha, isEuCaptchaDone } from "@myrasec/eu-captcha";

const captchaSitekey = "EUCAPTCHA_SITE_KEY";

export function ContactForm() {
  function handleSubmit(e: React.FormEvent<HTMLFormElement>): void {
    e.preventDefault();
    if (!isEuCaptchaDone()) {
      // challenge not yet complete
      return;
    }
    // proceed with form submission
  }

  return (
    <form onSubmit={handleSubmit}>
      {/* your fields */}
      <EuCaptcha sitekey={captchaSitekey} />
      <button type="submit">Submit</button>
    </form>
  );
}

Note

You can test the embedding with an invented sitekey. For an unknown sitekey, the CAPTCHA operates with the default values, and all traffic goes through.

Properties

These properties are available:

Property Type Default Effect
sitekey string Public sitekey. The value is necessary.
theme string "light" Appearance, values "light" and "dark".
width number 330 Width of the widget in pixels.
height number 100 Height of the widget in pixels.
widgetId string Your own identifier of the widget. Without a value, the package makes an identifier. For euCaptcha.execute(), the value is necessary.
autostart boolean true Starts the challenge automatically. The false value delays the start until the euCaptcha.execute(widgetId) call.
onComplete (token: string) => void Is called with the token as soon as the challenge passed.
onExpired () => void Is called when the token expires. A token expires 60 minutes after the solution.
onError () => void Is called when a network error or a server error occurs.

Examples of the appearance:

<EuCaptcha sitekey={captchaSitekey} theme="dark" />
<EuCaptcha sitekey={captchaSitekey} width={280} />
<EuCaptcha sitekey={captchaSitekey} height={60} />

Use the callbacks

<EuCaptcha
  sitekey={captchaSitekey}
  onComplete={(token: string) => console.log("token:", token)}
  onExpired={() => console.log("token expired")}
  onError={() => console.log("challenge error")}
/>

Delay the start of the challenge

Set autostart to false and give an identifier:

<EuCaptcha
  sitekey={captchaSitekey}
  widgetId="my-captcha"
  autostart={false}
/>

<button onClick={() => (window as any).euCaptcha.execute("my-captcha")}>Verify</button>

Next.js

The component uses interfaces of the browser. Thus, it operates only in the browser.

In the App Router, put 'use client' at the start of the file:

'use client';

import { EuCaptcha, isEuCaptchaDone } from "@myrasec/eu-captcha";

In the Pages Router, load the component with next/dynamic and without rendering on the server:

import dynamic from "next/dynamic";
import { isEuCaptchaDone } from "@myrasec/eu-captcha";

const EuCaptcha = dynamic(
  () => import("@myrasec/eu-captcha").then((m) => m.EuCaptcha),
  { ssr: false }
);

The same procedure applies to Gatsby, because Gatsby also uses the @myrasec/eu-captcha package.

Use the package without React

You can also use the package without React. React stays a dependency of the package.

Proceed as follows to use the package without React:

  • Load the parts asynchronously:
import { loadEuCaptcha, isEuCaptchaDone } from "@myrasec/eu-captcha";

loadEuCaptcha();
  • Add the element to the form:
<div class="eu-captcha" data-sitekey="EUCAPTCHA_SITE_KEY"></div>
  • The widget is rendered in the form.

The permitted attributes are given in HTML and JavaScript.

Get the condition

Before the transmission, examine if the challenge passed:

import { isEuCaptchaDone } from "@myrasec/eu-captcha";

function handleSubmit(e: React.FormEvent<HTMLFormElement>): void {
    e.preventDefault();

    if (!isEuCaptchaDone()) {
        // challenge not yet complete
        return;
    }
    // proceed with form submission
}

As an alternative, wait for the euCaptchaDone message at the window:

function listenForCaptchaDone(msg: MessageEvent): void {
    if (msg.data.type === "euCaptchaDone") {
        // enable submit button, update state, etc.
    }
}

window.addEventListener("message", listenForCaptchaDone, false);

Warning

The verification in the browser controls only the operation. Always also verify the token on the server. See Verify a client token.

Full example

See React and PHP.