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
<script src="https://gkcaptcha.gatekeeper.sa/widget/gk-captcha.js" async defer></script>NPM
npm install @gkcaptcha/reactimport { 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.
| Attribute | Values | Default | Description |
|---|---|---|---|
sitekey | pk_live_… | Required | Your public site key from the dashboard. It starts with pk_. Never put your secret key here. |
mode | checkboxinvisible | checkbox | checkbox shows a box the visitor clicks. invisible shows no box and verifies in the background. |
theme | lightdarkauto | auto | Color theme. auto follows the page and the visitor's system setting. |
size | normalcompact | normal | Widget size. |
lang | enar… | 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. |
challengeurl | https://… | Same host as the script | Optional. 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. |
verifyurl | https://… | Same host as the script | Optional. 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.
| Event | Detail | When 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. |
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
| Code | Meaning | What to do |
|---|---|---|
network-error | The widget could not reach gkCAPTCHA. | Check the visitor's connection and any firewall. The visitor can try again. |
challenge-expired | The challenge expired before it was solved. | The visitor can try again. |
verification-failed | The check did not pass. The reason is not shown, by design, so bots learn nothing from it. | The visitor can try again. |
invalid-site-key | The sitekey attribute is missing or wrong. | Set sitekey to the site key from your dashboard. It starts with pk_. |
rate-limited | Too many attempts in a short time. | Wait a moment, then try again. |
browser-unsupported | The 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.
| Method | Returns | Description |
|---|---|---|
execute() | void | Starts 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() | void | Clears 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() | void | Removes 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. |
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
| Name | Added | Removed |
|---|---|---|
gk-captcha-token | When 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