@botpoison/browser
The browser library for Botpoison Challenge,
an invisible alternative to CAPTCHAs for web forms. When a visitor presses
Send, the library fetches a signed proof-of-work puzzle, solves it in the
browser and attaches the answer to the form. The visitor sees no puzzle, no
checkbox and no widget. Your server then checks the answer with one call, for
example with @botpoison/node.
- No dependencies. Load it
async. - Sets no cookies and stores nothing in the browser.
- Needs
BigIntand Web Crypto, so the page must be served over HTTPS (or from localhost).
You need a project's public key (pk_...). Create a project for free at
botpoison.com.
A plain HTML form
No JavaScript to write. Add the script and put your public key on the form:
<script
src="https://unpkg.com/@botpoison/[email protected]/dist/index.js"
integrity="sha384-Coq4yXcH6P37EoKbvbmZZj3UpsLwU5Ir/tth7Fgf24Q5JUj2I4hcwqtj3zKi7+PA"
crossorigin="anonymous"
async
></script>
<form action="/contact" method="POST" data-botpoison-public-key="pk_xxxxxxxx">
<!-- your fields -->
<button type="submit">Send</button>
</form>
On submit the library solves the puzzle, adds a hidden _botpoison field and
sends the form. It fires botpoison-challenge-start,
botpoison-challenge-success and botpoison-challenge-error on the form. On
an error the form is not sent: listen for botpoison-challenge-error to tell
the visitor what happened.
A form sent before the script loads has no _botpoison. To prevent that, keep
Send disabled until the script fires botpoison-ready
(example).
A form sent with JavaScript
npm install @botpoison/browser
import Botpoison from "@botpoison/browser";
const botpoison = new Botpoison({ publicKey: "pk_xxxxxxxx" });
form.addEventListener("submit", async (event) => {
event.preventDefault();
const { solution } = await botpoison.challenge();
await fetch("/contact", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ ...fields, _botpoison: solution }),
});
});
challenge() rejects when the puzzle cannot be fetched or solved, for example
when the API is out of reach. challenge({ onProgress }) reports progress
from 0 to 1 while it solves.
On your server
Send the _botpoison value to /verify with your secret key, and accept the
submission only when it answers ok: true. See
verifying it on your server
for Node.js, PHP, Python, Go, Rust, Java and plain HTTP.