Files
cap/docs/guide/widget.md
T

159 lines
5.5 KiB
Markdown
Raw Normal View History

2025-01-18 13:46:25 +00:00
# @cap.js/widget
2025-12-21 13:35:40 +00:00
[![](https://data.jsdelivr.com/v1/package/npm/@cap.js/wasm/badge)](https://www.jsdelivr.com/package/npm/@cap.js/wasm)
2025-12-21 13:28:54 +00:00
2025-09-23 17:18:31 +01:00
`@cap.js/widget` is Cap's client-side library. It includes the `cap-widget` web component, the invisible mode and the CAPTCHA solver. First, add it to your client-side code:
2025-01-18 13:46:25 +00:00
2025-04-22 14:41:19 +01:00
::: code-group
2025-09-23 17:26:56 +01:00
```html[jsdelivr]
2025-01-18 13:46:25 +00:00
<script src="https://cdn.jsdelivr.net/npm/@cap.js/widget"></script>
2025-09-23 17:26:56 +01:00
<!-- we're using the latest version of the library here for simplicity, but you should optimally pin a specific version to avoid breaking changes in the future. -->
2025-01-18 13:46:25 +00:00
```
2025-09-23 17:26:56 +01:00
```html[unpkg]
2025-04-22 14:41:19 +01:00
<script src="https://unpkg.com/@cap.js/widget"></script>
2025-09-23 17:26:56 +01:00
<!-- we're using the latest version of the library here for simplicity, but you should optimally pin a specific version to avoid breaking changes in the future. -->
2025-04-22 14:41:19 +01:00
```
2025-05-07 19:30:12 +01:00
2025-09-23 17:26:56 +01:00
```js[bundler]
// npm: npm i @cap.js/widget
// pnpm: pnpm install @cap.js/widget
// bun: bun add @cap.js/widget
2025-05-30 18:35:14 +01:00
2025-09-23 17:18:31 +01:00
import Cap from '@cap.js/widget';
2025-09-23 17:26:56 +01:00
// ...
2025-09-23 17:18:31 +01:00
```
2025-09-23 17:26:56 +01:00
```html[standalone server]
<script>
window.CAP_CUSTOM_WASM_URL = "https://<server url>/assets/cap_wasm.js";
</script>
<script src="https://<server url>/assets/widget.js"></script>
```
2025-05-21 16:36:02 +01:00
:::
2025-01-18 13:46:25 +00:00
You can now use the `<cap-widget>` component in your HTML.
```html
2025-05-30 18:35:14 +01:00
<cap-widget id="cap" data-cap-api-endpoint="<your cap endpoint>"></cap-widget>
2025-01-18 13:46:25 +00:00
```
2025-09-23 17:26:56 +01:00
**Note:** You'll need to start a server with an API exposing the Cap methods running at the same URL as specified in the `data-cap-api-endpoint` attribute.
2025-01-18 13:46:25 +00:00
2025-09-23 17:26:56 +01:00
The following attributes are supported:
- `data-cap-api-endpoint`: API endpoint (required if not using custom fetch)
- `data-cap-worker-count`: Number of workers to use (defaults to `navigator.hardwareConcurrency || 8`)
- `onsolve=""`: Event listener for the `solve` event
- [i18n attributes](#i18n)
2025-01-18 13:46:25 +00:00
Then, in your JavaScript, listen for the `solve` event to capture the token when generated:
2025-09-23 17:26:56 +01:00
```js
2025-01-18 13:46:25 +00:00
const widget = document.querySelector("#cap");
2025-04-12 13:39:56 +01:00
widget.addEventListener("solve", function (e) {
2025-01-18 13:46:25 +00:00
const token = e.detail.token;
2025-04-12 13:39:56 +01:00
2025-09-23 17:26:56 +01:00
// handle the token as needed
2025-01-18 13:46:25 +00:00
});
```
2025-04-23 14:52:50 +01:00
Alternatively, you can use `onsolve=""` directly within the widget or wrap the widget in a `<form></form>` (where Cap will automatically submit the token alongside other form data. for this, it'll create a hidden field with name set to its `data-cap-hidden-field-name` attribute or `cap-token`).
2025-01-18 13:46:25 +00:00
2025-09-23 17:18:31 +01:00
## Invisible mode
You can use `new Cap({ ... })` in your client-side JavaScript to create a new Cap instance and use the `solve()` method to solve the challenge. This is helpful for situations where you don't want the Cap widget to be visible but still want security, e.g. on a social media app when posting something.
```js
import Cap from '@cap.js/widget';
const cap = new Cap({
2025-11-14 15:19:42 +00:00
apiEndpoint: '/api/cap/'
2025-09-23 17:18:31 +01:00
});
const token = await cap.solve();
```
2025-01-18 13:46:25 +00:00
## Supported events
2025-04-12 13:39:56 +01:00
The following custom events are supported:
2025-01-18 13:46:25 +00:00
- `solve`: Triggered when the token is generated.
- `error`: Triggered when an error occurs.
- `reset`: Triggered when the widget is reset.
2025-05-30 17:52:07 +01:00
- `progress`: Triggered when there's a progress update while in verification.
2025-04-22 13:42:58 +01:00
2025-05-07 19:30:12 +01:00
## i18n
You can change the text on each label of the widget by setting the `data-cap-i18n-*` attribute, like this:
```html
<cap-widget
id="cap"
2025-05-30 18:35:14 +01:00
data-cap-api-endpoint="<your cap endpoint>"
2025-05-07 19:30:12 +01:00
data-cap-i18n-verifying-label="Verifying..."
data-cap-i18n-initial-state="I'm a human"
data-cap-i18n-solved-label="I'm a human"
data-cap-i18n-error-label="Error"
data-cap-i18n-wasm-disabled="Enable WASM for significantly faster solving"
2025-05-07 19:30:12 +01:00
></cap-widget>
```
2025-06-16 14:18:28 +01:00
`verify-aria-label`, `verifying-aria-label`, `verified-aria-label`, `error-aria-label` are also supported for screen readers.
2025-06-13 14:53:42 +01:00
## Customizing the widget
2025-05-07 19:30:12 +01:00
2025-06-13 14:53:42 +01:00
### fetch function
You can override the default browser fetch implementation by setting `window.CAP_CUSTOM_FETCH` to a custom function. This function will receive the URL and options as arguments and should return a promise that resolves to the response.
2025-04-22 13:42:58 +01:00
```js
window.CAP_CUSTOM_FETCH = function (url, options) {
2025-09-23 17:18:31 +01:00
// … add your custom fetch implementation
2025-04-22 13:42:58 +01:00
return fetch(url, options);
};
2025-05-07 19:30:12 +01:00
```
2025-05-09 14:45:13 +01:00
2025-06-13 14:53:42 +01:00
## WASM URL
2025-05-09 14:45:13 +01:00
2025-05-24 09:09:18 +01:00
You can override the default WASM URL by setting `window.CAP_CUSTOM_WASM_URL` to a custom URL. This URL will be used to load the WASM module. This defaults to `https://cdn.jsdelivr.net/npm/@cap.js/wasm@0.0.4/browser/cap_wasm.min.js`
2025-06-13 14:53:42 +01:00
2025-07-29 12:24:09 +01:00
## Customizing
2025-06-13 14:53:42 +01:00
You can fully change how the widget looks by setting various CSS variables on the `cap-widget` element. The following CSS variables are supported:
```css
cap-widget {
--cap-background: #fdfdfd;
--cap-border-color: #dddddd8f;
--cap-border-radius: 14px;
--cap-widget-height: 30px;
--cap-widget-width: 230px;
--cap-widget-padding: 14px;
--cap-gap: 15px;
--cap-color: #212121;
--cap-checkbox-size: 25px;
--cap-checkbox-border: 1px solid #aaaaaad1;
--cap-checkbox-border-radius: 6px;
--cap-checkbox-background: #fafafa91;
--cap-checkbox-margin: 2px;
2025-06-16 14:18:28 +01:00
--cap-font: system, -apple-system, "BlinkMacSystemFont", ".SFNSText-Regular", "San Francisco",
"Roboto", "Segoe UI", "Helvetica Neue", "Lucida Grande", "Ubuntu", "arial", sans-serif;
2025-06-13 14:53:42 +01:00
--cap-spinner-color: #000;
--cap-spinner-background-color: #eee;
--cap-spinner-thickness: 5px;
2025-07-29 12:24:09 +01:00
--cap-checkmark: url("data:image/svg+xml,...");
--cap-error-cross: url("data:image/svg+xml,...");
2025-06-13 14:53:42 +01:00
}
2025-06-16 14:18:28 +01:00
```
2025-09-23 17:18:31 +01:00
2025-10-05 19:04:35 +01:00
<small>Note: you _can_ technically hide the "Cap" label, but we kindly ask you to leave it visible. It's unobtrusive, doesn't track users, lightweight, and helps Cap grow.</small>
2025-09-23 17:18:31 +01:00
## Types
Cap's widget is fully typed. You can find the type definitions in the `cap.d.ts` file.