ALTCHA uses a proof-of-work mechanism to protect your website, APIs, and online services from spam and abuse. Unlike other solutions, ALTCHA is self-hosted, does not use cookies nor fingerprinting, does not track users, and is fully compliant with GDPR.
- Friction-less - Using PoW instead of visual puzzles.
- Cookie-less - GDPR compliant by design.
- Self-hosted - Without reliance on external providers.
ALTCHA widget is distributed as a "Web Component" and supports all modern browsers.
npm install altcha
import altcha
in your main file:
import 'altcha';
or insert <script>
tag to your website:
<script async defer src="/altcha.js" type="module"></script>
CDN: https://cdn.jsdelivr.net/gh/altcha-org/altcha@main/dist/altcha.min.js
<form>
<altcha-widget
challengeurl="https://..."
></altcha-widget>
</form>
See the configuration below or visit the website integration documentation.
See server documentation for more details.
Required options (at least one is required):
- challengeurl - URL of your server to fetch the challenge from. Refer to server integration.
- challengejson - JSON-encoded challenge data. If avoiding an HTTP request to
challengeurl
, provide the data here.
Additional options:
- auto - Automatically verify without user interaction (possible values:
onload
,onsubmit
). - expire - The challenge expiration (duration in milliseconds).
- hidefooter - Hide the footer (ALTCHA link).
- hidelogo - Hide the ALTCHA logo.
- maxnumber - The max. number to iterate to (defaults to 1,000,000).
- name - The name of the hidden field containing the payload (defaults to "altcha").
- strings - JSON-encoded translation strings. Refer to customization.
- refetchonexpire - Automatically re-fetch and re-validate when the challenge expires (defaults to true).
- workers - The number of workers to utilize for PoW (defaults to
navigator.hardwareConcurrency || 8
).
Development / testing options:
- debug - Print log messages in the console.
- mockerror - Causes the verification to always fail with a "mock" error.
- test - Generates a "mock" challenge within the widget, bypassing the request to
challengeurl
.
To configure the widget programmatically, use the configure()
method:
document.querySelector('#altcha').configure({
challenge: {
algorithm: 'SHA-256',
challenge: '...',
salt: '...',
signature: '...',
},
strings: {
label: 'Verify',
},
});
Available configuration options:
export interface Configure {
auto?: 'onload' | 'onsubmit';
challenge?: {
algorithm: string;
challenge: string;
salt: string;
signature: string;
};
debug?: boolean;
expire?: number;
hidefooter?: boolean;
hidelogo?: boolean;
maxnumber?: number;
mockerror?: boolean;
name?: string;
refetchonexpire?: boolean;
strings?: {
error?: string;
footer?: string;
label?: string;
verified?: string;
verifying?: string;
waitAlert?: string;
};
test?: boolean;
workers?: number;
}
- statechange - Triggers whenever an internal
state
changes. - verified - Triggers when the challenge is verified.
enum State {
ERROR = 'error',
VERIFIED = 'verified',
VERIFYING = 'verifying',
UNVERIFIED = 'unverified',
EXPIRED = 'expired',
};
Using events:
document.querySelector('#altcha').addEventListener('statechange', (ev) => {
// See enum State above
console.log('state:', ev.detail.state);
});
Important
Both programmatic configuration and event listeners have to called/attached after the ALTCHA script loads, such as within window.addEventListener('load', ...).
See Contributing Guide and please follow our Code of Conduct.
MIT