Widget Configuration

Every attribute, event and method the gk-captcha element supports.

Only the attributes, events and methods on this page are supported. Anything not listed may change without notice.

Installation

CDN

index.html
<script src="https://gkcaptcha.gatekeeper.sa/widget/gk-captcha.js" async defer></script>

NPM

terminal
npm install @gkcaptcha/react
app.js
import { GkCaptcha } from '@gkcaptcha/react';

export function MyForm() {
  return (
    <GkCaptcha
      siteKey="pk_live_..."
      onVerify={(token) => console.log('Verified:', token)}
    />
  );
}

Attributes

Set these on the gk-captcha element. Names are lowercase and have no data- prefix.

AttributeValuesDefaultDescription
sitekeypk_live_…RequiredYour public site key from the dashboard. It starts with pk_. Never put your secret key here.
modecheckboxinvisiblecheckboxcheckbox shows a box the visitor clicks. invisible shows no box and verifies in the background.
themelightdarkautoautoColor theme. auto follows the page and the visitor's system setting.
sizenormalcompactnormalWidget size.
langenar…Visitor's browser language (English if not supported)Widget language, one of 21: ar de en es fa fr hi id it ja ko ms nl pl pt ru th tr ur vi zh. Arabic, Persian and Urdu display right to left.
challengeurlhttps://…Same host as the scriptOptional. Full http(s) address of the challenge endpoint. Set it only when the API runs on a different host from the script, for example on-premises.
verifyurlhttps://…Same host as the scriptOptional. Full http(s) address of the verification endpoint. Set it only when the API runs on a different host from the script, for example on-premises.

Set challengeurl and verifyurl as attributes with setAttribute(). The widget does not read them as JavaScript properties. The React and Vue packages already set them as attributes.

Events

Every public event name starts with captcha-. All three bubble, so a listener on document also receives them, and e.target is the widget that fired.

EventDetailWhen it fires
captcha-verified{ token }Verification succeeded. The same token is in the gk-captcha-token form field.
captcha-expired{}The token expired before it was used. The form field is cleared and the widget can verify again.
captcha-error{ code, message }Verification did not complete. code is one of the six error codes below.
app.js
const captcha = document.querySelector('gk-captcha');

captcha.addEventListener('captcha-verified', (event) => {
  // The token is also in the form's gk-captcha-token field.
  console.log('Verified:', event.detail.token);
});

captcha.addEventListener('captcha-expired', () => {
  // The token expired. The widget is ready to verify again.
});

captcha.addEventListener('captcha-error', (event) => {
  console.warn('gkCAPTCHA error:', event.detail.code);
});

Error codes

CodeMeaningWhat to do
network-errorThe widget could not reach gkCAPTCHA.Check the visitor's connection and any firewall. The visitor can try again.
challenge-expiredThe challenge expired before it was solved.The visitor can try again.
verification-failedThe check did not pass. The reason is not shown, by design, so bots learn nothing from it.The visitor can try again.
invalid-site-keyThe sitekey attribute is missing or wrong.Set sitekey to the site key from your dashboard. It starts with pk_.
rate-limitedToo many attempts in a short time.Wait a moment, then try again.
browser-unsupportedThe browser is missing a feature the widget needs.Ask the visitor to update their browser.

Methods

Wait for customElements.whenDefined('gk-captcha') before you call a method.

MethodReturnsDescription
execute()voidStarts verification. If called before the widget is ready, it runs once the widget is ready.
getToken()Promise<string>Resolves with a valid token and starts verification if needed. Never returns an expired token. Rejects on failure or timeout.
reset()voidClears the token and the form field. The widget returns to its start state.
getState()'idle' | 'verified' | 'error'The current state. Any other value means verification is in progress.
el.remove()voidRemoves the widget and stops all its work. A standard browser method.
customElements.whenDefined('gk-captcha')Promise<…>Resolves when the widget script has loaded. A standard browser method.
app.js
const form = document.querySelector('#signup-form');
const captcha = document.createElement('gk-captcha');
captcha.setAttribute('sitekey', 'pk_live_...');
captcha.setAttribute('mode', 'invisible');
form.appendChild(captcha);

form.addEventListener('submit', async (event) => {
  event.preventDefault();
  try {
    await customElements.whenDefined('gk-captcha');
    await captcha.getToken(); // also fills the gk-captcha-token field
    // URL-encoded, so a standard express.urlencoded() server reads req.body['gk-captcha-token'].
    await fetch(form.action, { method: 'POST', body: new URLSearchParams(new FormData(form)) });
  } catch (error) {
    // Show an error message. Never send the form without a token.
  } finally {
    captcha.reset(); // each token works once
  }
});

Form field

NameAddedRemoved
gk-captcha-tokenWhen verification succeeds. It is a hidden input inside the widget element, so it is inside your form.On reset(), when captcha-expired fires, and when the element is removed.

On your server, read gk-captcha-token and send it to POST /api/v1/token/verify.

Accessibility

The widget is fully accessible and meets WCAG 2.2 AA standards:

  • Full keyboard navigation (Tab, Enter, Space)
  • Screen reader announcements
  • High contrast support
  • Focus indicators
  • RTL layout support for Arabic