Logo
Docs

Mini (Cap.js)

The Mini Widget is based on Cap.js but has a different implementation which suites the Compatibility needs for Before.sh Captcha-as-a-Service.

Installation

Include the script in your HTML:

<script src="https://cdn.hopjs.net/npm/@before.sh/mini@1.4.2/cap.min.js"></script>

or

<script src="https://cdn.jsdelivr.net/npm/@before.sh/mini@1.4.2/cap.min.js"></script>

Usage

The widget can be embedded using the <cap-mini> custom element with a site key:

<cap-mini cap-site-key="YOUR_SITE_KEY"></cap-mini>

It will automatically detect an endpoint, and therefore doesn't need to specify one.

Invisible Mode

The widget can be controlled programmatically without visible UI:

const captcha = new Cap({
  apiEndpoint: '/api/'
});

// Trigger solve programmatically
captcha.solve();

// Listen for completion
captcha.addEventListener('solve', (event) => {
  console.log('Token:', event.detail.token);
});

When no DOM element is provided to the constructor, the widget is automatically hidden with display: none and appended to the document.

Configuration Attributes

Current Naming Convention (v1.4.2+)

AttributeTypeDescription
cap-site-keystringSite key for authentication (new API mode)
cap-endpointsstringComma-separated list of fallback endpoints (optional)
cap-api-endpointstringAPI endpoint URL (legacy mode)
cap-darkmodebooleanEnables dark theme when set to "true"
cap-labelbooleanShows Cap.js attribution when "true", before.sh branding when "false" (default: "true")
cap-colorstringPrimary color for border and brand highlight (e.g., "#242424")
cap-worker-countnumberNumber of Web Workers for parallel computation (default: hardware concurrency)
cap-hidden-field-namestringName attribute for the hidden token input field (default: "cap-token")

Legacy Naming Convention

The following attribute names are supported for backwards compatibility:

  • data-cap-site-keycap-site-key
  • data-cap-endpointscap-endpoints
  • data-cap-api-endpointcap-api-endpoint
  • darkmodecap-darkmode
  • colorcap-color
  • data-cap-worker-countcap-worker-count
  • data-cap-hidden-field-namecap-hidden-field-name

Internationalization

Text displayed by the widget can be customized using cap-i18n-* or data-cap-i18n-* attributes:

AttributeDefault ValueWhen Displayed
cap-i18n-initial-state"I'm a human"Initial state
cap-i18n-verifying-label"Verifying..."During verification
cap-i18n-solved-label"You're a human"After successful verification
cap-i18n-error-label"Error. Try again."On error
cap-i18n-verify-aria-label"Click to verify you're a human"ARIA label (initial)
cap-i18n-verifying-aria-label"Verifying you're a human, please wait"ARIA label (verifying)
cap-i18n-verified-aria-label"We have verified you're a human, you may now continue"ARIA label (verified)
cap-i18n-error-aria-label"An error occurred, please try again"ARIA label (error)
cap-i18n-wasm-disabled"Enable WASM for significantly faster solving"Warning when WebAssembly unavailable

Example:

<cap-mini
  cap-site-key="YOUR_SITE_KEY"
  cap-i18n-initial-state="Ich bin ein Mensch"
  cap-i18n-verifying-label="Überprüfung läuft...">
</cap-mini>

Styling

CSS Custom Properties

The widget accepts CSS custom properties for styling:

PropertyDefaultDescription
--cap-background#fdfdfdBackground color (light mode)
--cap-background-dark#1a1a1aBackground color (dark mode)
--cap-border-colorvar(--cap-primary-color, #d946ef)Border color (light mode)
--cap-border-color-darkvar(--cap-primary-color, #d946ef)Border color (dark mode)
--cap-border-radius14pxBorder radius
--cap-color#212121Text color (light mode)
--cap-color-dark#e5e5e5Text color (dark mode)
--cap-primary-color#d946efPrimary accent color (border and brand highlight)
--cap-widget-height72pxWidget height
--cap-widget-width230pxWidget width
--cap-widget-padding14pxInternal padding
--cap-gap15pxGap between elements
--cap-checkbox-size25pxCheckbox dimensions
--cap-checkbox-background#fafafa91Checkbox background (light)
--cap-checkbox-background-dark#2a2a2aCheckbox background (dark)
--cap-checkbox-border1px solid #aaaaaad1Checkbox border
--cap-checkbox-border-dark#555Checkbox border color (dark)
--cap-checkbox-border-radius100%Checkbox border radius
--cap-checkbox-margin2pxCheckbox vertical margin
--cap-spinner-color#000Loading spinner color
--cap-spinner-background-color#eeeLoading spinner background
--cap-spinner-thickness5pxLoading spinner thickness
--cap-fontsystem fontsFont family
--cap-checkmarkSVG data URISuccess checkmark icon
--cap-error-crossSVG data URIError icon

Example:

<style>
  cap-mini {
    --cap-primary-color: #242424;
    --cap-border-radius: 8px;
    --cap-widget-width: 300px;
  }
</style>

Shadow Parts

The widget exposes CSS parts for styling via ::part():

  • checkbox - The checkbox/spinner element
  • label - The text label
  • attribution - The attribution link

Example:

cap-mini::part(label) {
  font-size: 16px;
}

JavaScript API

Programmatic Control

const widget = document.querySelector('cap-mini');

// Trigger verification
widget.solve();

// Reset widget
widget.reset();

// Access token value
console.log(widget.token);

Events

The widget dispatches the following events:

EventDetail PropertiesDescription
solve{ token: string }Fired when verification completes successfully
progress{ progress: number }Fired during solving (0-100)
error{ isCap: boolean, message: string }Fired when an error occurs
resetnoneFired when widget is reset

Example:

widget.addEventListener('solve', (event) => {
  console.log('Token:', event.detail.token);
  // Token is also available in hidden input field
});

widget.addEventListener('progress', (event) => {
  console.log('Progress:', event.detail.progress + '%');
});

widget.addEventListener('error', (event) => {
  console.error('Error:', event.detail.message);
});

Event Attributes

Events can also be handled via HTML attributes:

<cap-mini
  cap-site-key="YOUR_SITE_KEY"
  onsolve="handleSolve"
  onprogress="handleProgress"
  onerror="handleError"
  onreset="handleReset">
</cap-mini>

<script>
function handleSolve(event) {
  console.log('Solved:', event.detail.token);
}
</script>

API Communication

New API (Site Key Mode)

When using cap-site-key, the widget makes two requests:

  1. Challenge Request (GET)

    • Endpoint: {endpoint}/{siteKey}/challenge
    • Returns: { challenge, token }
  2. Redeem Request (POST)

    • Endpoint: {endpoint}/{siteKey}/redeem
    • Body: { token, solutions }
    • Returns: { success: boolean, token: string, expires: string }

Legacy API (Endpoint Mode)

When using cap-api-endpoint, the widget makes two requests:

  1. Challenge Request (POST)

    • Endpoint: {apiEndpoint}challenge
    • Returns: { challenge, token }
  2. Redeem Request (POST)

    • Endpoint: {apiEndpoint}redeem
    • Body: { token, solutions }
    • Returns: { success: boolean, token: string, expires: string }

Fallback and Retry Behavior

In site key mode with multiple endpoints:

  • Each endpoint is tried sequentially
  • Each endpoint gets up to 3 attempts (configurable)
  • Exponential backoff between retries (1s, 2s, 4s, max 5s)
  • Request timeout: 10 seconds
  • Client errors (400, 401, 403) skip retries

Token Handling

Upon successful verification:

  1. Token is stored in widget.token property
  2. Token is set in a hidden input field (name configurable via cap-hidden-field-name)
  3. Token automatically expires based on server response
  4. Widget automatically resets when token expires

WebAssembly

The widget uses WebAssembly for SHA-256 computation when available. Files are prefetched on load:

  • https://cdn.jsdelivr.net/npm/@cap.js/wasm@0.0.6/browser/cap_wasm.min.js
  • https://cdn.jsdelivr.net/npm/@cap.js/wasm@0.0.6/browser/cap_wasm_bg.wasm

Prefetch uses <link rel="prefetch"> which does not block page load or make API requests.

When WebAssembly is unavailable, a JavaScript fallback is used with a warning message displayed.

Custom Configuration

Custom Fetch Function

Override the fetch implementation:

window.CAP_CUSTOM_FETCH = async (url, options) => {
  // Custom fetch logic
  return fetch(url, options);
};

Custom WASM URL

Override the WASM library location:

window.CAP_CUSTOM_WASM_URL = 'https://your-cdn.com/cap_wasm.min.js';

Custom CSS Nonce

Add a nonce for Content Security Policy:

window.CAP_CSS_NONCE = 'your-nonce-value';

The nonce will be added to the <style> tag: <style nonce="your-nonce-value">.

Accessibility

The widget includes ARIA attributes:

  • role="button" - Identifies the widget as interactive
  • tabindex="0" - Allows keyboard focus
  • aria-label - Describes current state (customizable via i18n attributes)
  • aria-live="polite" - Announces state changes to screen readers

Keyboard interaction:

  • Enter or Space key triggers verification

Browser Compatibility

Required features:

  • Custom Elements (Web Components)
  • Shadow DOM
  • Web Workers
  • ES6+ syntax
  • Optional: WebAssembly (fallback implemented)

License

Apache-2.0