Skip to content

HTML Integration

This page covers the complete HTML-level integration of the EU CAPTCHA widget for server-rendered HTML pages.

Using React, Vue, Angular, or another SPA framework? Do not add the <script> tag manually. Use the dedicated framework packages instead — see SPA Framework Integration.

1. Load the script

Add the following <script> tag inside your <head>:

<script src="https://cdn.eu-captcha.eu/verify.js" async defer></script>

Load this on every page that contains a form you want to protect. The script is small and loads asynchronously.

2. Place the widget

Add the widget <div> inside your <form>, typically just before the submit button:

<form method="POST" action="/your-endpoint">
  <!-- your fields -->

  <div class="eu-captcha" data-sitekey="EUCAPTCHA_SITE_KEY"></div>

  <button type="submit">Submit</button>
</form>

Replace EUCAPTCHA_SITE_KEY with the public sitekey from your dashboard.

By default the widget runs the challenge automatically when the page loads. When the challenge completes, a hidden input field named eu-captcha-response is added to the form:

<input type="hidden" name="eu-captcha-response" value="<token>" />

This token is included in the form POST and must be verified on your server.

Widget attributes

Attribute Required Default Description
data-sitekey Your public sitekey
data-theme "light" Visual theme: "light" or "dark" (case-insensitive)
data-width 330 Widget width in pixels (finite number)
data-height 100 Widget height in pixels (minimum 48)
data-widgetid Custom widget ID; auto-generated if omitted
data-autostart true Set to "false" to defer the challenge until euCaptcha.execute() is called
data-callback Global function name called on successful completion (receives token)
data-expired-callback Global function name called when the token expires
data-error-callback Global function name called on challenge failure

See JavaScript API for full attribute details, the euCaptcha.execute() API, the window.getEuCaptchaElement() function, and the postMessage events the widget emits.

Multiple forms on one page

If your page has more than one protected form, add a separate .eu-captcha div inside each <form>. Each widget instance operates independently.

<!-- Form 1 -->
<form id="login-form" method="POST" action="/login">
  <input type="email" name="email" />
  <input type="password" name="password" />
  <div class="eu-captcha" data-sitekey="EUCAPTCHA_SITE_KEY"></div>
  <button type="submit">Log in</button>
</form>

<!-- Form 2 -->
<form id="newsletter-form" method="POST" action="/subscribe">
  <input type="email" name="email" />
  <div class="eu-captcha" data-sitekey="EUCAPTCHA_SITE_KEY"></div>
  <button type="submit">Subscribe</button>
</form>

Framework packages

For React, Vue, Angular, and other single-page application frameworks, use the dedicated npm packages rather than the plain script tag. See SPA Framework Integration for installation, component usage, props, and how to check completion state before submitting.

Troubleshooting

Widget doesn't appear — check that the script loaded successfully (browser DevTools → Network). Ensure the sitekey value is correct.

Token not appearing in submitted form data — the challenge may not have completed before the user submitted. Consider only enabling the submit button after the widget signals completion.