Widget
Every attribute, the three modes and the JavaScript API for forms loaded later.
Widget options
The widget is configured through data- attributes. They sit on the container carrying data-captchacore-widget, some additionally on the form. Every value here overrides the default you set for the site in the admin panel.
| Attribute | Values | Default | Description |
|---|---|---|---|
| data-theme | auto | light | dark | auto | Colour scheme. auto follows the visitor's system setting. |
| data-color | Hex colour | #34d399 | Accent colour for checkbox and border |
| data-label | Text | depends on the language | Label next to the checkbox |
| data-brand | Text or empty | CaptchaCore | Branding on the right, empty = hidden |
| data-size | normal | compact | normal | normal is 360 px wide, compact 300 px |
| data-lang | de en fr es it nl pl pt tr ja zh ko ar ru | language of the page | Language of the widget texts. Without a value, lang on the form counts, otherwise the one on the <html> element. |
| data-start | auto | focus | none | auto | When the check starts: immediately, on first focus in the form, or only on click. |
| data-mode | interactive | visible | invisible | interactive | Overrides the mode set in the admin panel for this one form. |
| data-form-type | login register contact comment checkout password_reset newsletter custom | — | Determines which form policy applies. Belongs on the form or the container. |
Attributes on the script tag
These values belong on the <script> element itself and apply to every widget on the page.
| Attribute | Required | Description |
|---|---|---|
| data-site-key | yes | Public key of the site (cc_pub_…). |
| data-service-url | yes | https://api.captchacore.eu |
| data-worker-url | no | Custom path to the proof-of-work worker, only needed with different hosting. |
| data-fail-open | no | Only false: the form waits instead of sending the placeholder cc-unavailable after a lasting connection error. |
Widget modes
The mode is set with data-mode="..." on the widget element <div data-captchacore-widget>; without it, the site setting from the customer area applies.
interactive
Recommended Widget always visible. The PoW is solved automatically. The checkbox ticks itself once enough human interaction is detected (2+ characters typed, mouse movement, 2+ seconds). No click needed for real users. Fallback: manual click.
visible
Widget visible. The user has to click the checkbox to start verification. Similar to reCAPTCHA v2.
invisible
No visible UI. The PoW is solved entirely in the background. The token is inserted automatically on submit. Ideal when no visible protection is wanted.
The widget's JavaScript API
The script creates the global object CaptchaCoreV2. On static pages you need none of it — the widget binds itself to every matching form on load. The API becomes relevant as soon as forms are loaded in via JavaScript, that is in shop systems, single-page applications and modal dialogues.
| Method | Purpose |
|---|---|
| CaptchaCoreV2.init(config) | Manual initialisation when the script was included without data attributes. Expects at least siteKey and serviceUrl. |
| CaptchaCoreV2.attach() | Scans for forms again and binds new ones. Call it after every DOM replacement. |
| CaptchaCoreV2.destroy() | Detaches all widgets, stops the observer and cleans up. Useful before a page change in an SPA. |
| CaptchaCoreV2.getWidgets() | Returns the currently bound widget instances. |
| CaptchaCoreV2.getWidget(form) | The widget of a specific form (element or CSS selector), otherwise null. |
| widget.getToken() | A token for exactly one /verify call, including the behavioral data collected since page load. Then immediately loads the next challenge — for AJAX forms with several submissions per page view. |
| CaptchaCoreV2.getLanguages() | List of the 14 supported language codes. |
| CaptchaCoreV2.on(event, fn) | Subscribe to an event. |
| CaptchaCoreV2.off(event, fn) | Cancel the subscription. |
Events
CaptchaCoreV2.on('ready', function (data) { // Widget ist gebunden und einsatzbereit }); CaptchaCoreV2.on('error', function (err) { // Netzwerkfehler, abgelaufener Nonce, ungültiger Schlüssel console.warn('CaptchaCore:', err); });
Forms loaded later
The widget watches the page content and picks up new forms carrying data-captchacore by itself. That covers most cases. If a form is replaced and submitted in the same breath, however, the observer can be too late — then call attach() explicitly after inserting it.
// Beispiel: Formular per fetch nachgeladen const html = await (await fetch(url)).text(); container.innerHTML = html; CaptchaCoreV2.attach(); // bindet das neue Formular an
Submitting forms via fetch()
If your form is sent via fetch() or XHR and allows several submissions per page view (search, domain check, cart), request a separate token with widget.getToken() before each request. Each token is valid for exactly one verification; the widget solves the next challenge in the background while the visitor keeps working. Concurrent calls are served one after another and never receive the same token.
const form = document.querySelector('#domaincheck'); form.addEventListener('submit', async (e) => { e.preventDefault(); const body = new FormData(form); try { body.set('captchacore_token', await CaptchaCoreV2.getWidget(form).getToken()); } catch { // Dienst nicht erreichbar: Platzhalter senden, Ihr Server entscheidet (Fail-Open) body.set('captchacore_token', 'cc-unavailable'); } const res = await fetch('/domaincheck', { method: 'POST', body, headers: { Accept: 'application/json' }, // Fehler als JSON statt Weiterleitung }); });
For shop and forum systems
Systems such as Shopware, WooCommerce or phpBB frequently swap registration, address forms and comment fields via AJAX. Hook attach() to the system's corresponding event, after the new content is in the DOM. A second call does no harm: already bound forms are skipped.