@flowenapp/svelte-hcaptcha
v2.0.2
Published
An <HCaptcha> component for Svelte 5 apps.
Readme
@flowenapp/svelte-hcaptcha
Overview
hCaptcha Component Library for Svelte 5.
hCaptcha is a drop-replacement for reCAPTCHA that protects user privacy, rewards websites, and helps companies get their data labeled. It's a simple way of proving that site users are human.
Sign up at hCaptcha to get your sitekey today. You need a sitekey to use this library.
This library is heavily inspired by react-hcaptcha and is built upon a svelte-hcaptcha fork.
Installation
You can install this library via npm:
bun add @flowenapp/svelte-hcaptcha
Usage
The two requirements for usage are the sitekey prop and a parent component such as a <form />. The HCaptcha component will automatically include and load the hCaptcha API library and append it to the parent component, ready for use.
The HCaptcha component accepts callback props which you can pass from the parent:
onmount- the component has been mountedonload- the hCaptcha API script has successfully loadedonsuccess- a user has successfully completed an hCaptcha challenge. The callback receives{ token }which can be used to verify the captchaonerror- something went wrong when the user attempted the captchaonclose- the captcha was closedonexpired- the captcha has expired and needs to be re-verified
You can read more about these events below. In particular, errors are described here.
If you don't supply the sitekey prop to the HCaptcha component, then it will try and load this from a window.sitekey variable. This approach can be useful e.g. when the component is to be mounted on a synchronously-rendered page, as you can inject the window.sitekey variable from a server backend.
Note also that it's not possible to develop against localhost or 127.0.0.1 when using this component. A useful tool in this scenario is ngrok. On Linux, you can also add an entry into /etc/hosts like 127.0.0.1 test.mydomain.com, then you can run svelte with --host test.mydomain.com. This is explained in the HCaptcha docs.
Basic usage
<script>
import HCaptcha, { CaptchaTheme } from '@flowenapp/svelte-hcaptcha';
const mySitekey = 'your-sitekey';
const handleSuccess = ({ token }) => {
console.log(token);
};
const handleError = () => {
console.error('Captcha error');
};
</script>
<form>
<HCaptcha
sitekey={mySitekey}
theme={CaptchaTheme.DARK}
onsuccess={handleSuccess}
onerror={handleError}
/>
</form>If you want to be able to reset the component (hint: you probably want to do this, for instance, if captcha verification fails), then you'll need to bind to it in the parent. The component exposes a .reset() method:
<script>
import HCaptcha from '@flowenapp/svelte-hcaptcha';
let captcha;
const handleError = () => {
captcha.reset();
};
</script>
<form>
<HCaptcha bind:this={captcha} onerror={handleError} />
</form>Props
| Name | Values/Type | Required | Default | Description |
| ----------------- | -------------- | -------- | ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| sitekey | String | Yes | - | This is your sitekey, this allows you to load captcha. If you need a sitekey, please visit hCaptcha, and sign up to get your sitekey. |
| apihost | String | No | https://js.hcaptcha.com/1/api.js | See enterprise docs. |
| hl | String | No | - | Forces a specific localization. See here for supported language codes. |
| reCaptchaCompat | Boolean | No | false | Disable drop-in replacement for reCAPTCHA with false to prevent hCaptcha from injecting into window.grecaptcha. |
| theme | CaptchaTheme | No | CaptchaTheme.LIGHT | hCaptcha supports a dark mode and a light mode. By default we render the light variant; set to CaptchaTheme.DARK to get the dark mode variant. |
Events
| Event | Params | Description |
| ----------- | ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| onsuccess | { token } | Fires when a user successfully completes a captcha challenge. Contains the token which is required to verify the captcha. |
| onload | - | Fires when the hCaptcha api script has finished loading. |
| onmount | - | Fires when the component is mounted. |
| onclose | - | Fires when the captcha is closed by the user (i.e. s/he has not completed it). |
| onerror | - | Fires when hCaptcha encounters an error and cannot continue. If you specify an error callback, you must inform the user that they should retry. |
| onexpired | - | Fires when the token is expired and needs to be re-verified. |
Methods
| Method | Description |
| ----------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| reset() | Reset the current challenge. |
| execute() | Trigger the HCaptcha workflow programmatically. See HCaptcha docs for details. |
Contributing
Pull requests, suggestions, comments, critiques - all welcome :)
Please get in touch with the maintainers if you need help or advice to get the project to run.
Developing
Install dependencies with bun install, then start a development server:
bun run dev
# or start the server and open the app in a new browser tab
bun run dev -- --openEverything inside src/lib is part of the library.
Building
To build this library:
bun run packageTo create a production version:
bun run buildYou can preview the production build with bun run preview.
Publishing
Releases are published automatically when you bump version in package.json and push to the default branch. CI creates the tag (e.g. v2.0.2) and publishes to npm in the same pipeline — GitLab does not start a separate pipeline for tags pushed with CI_JOB_TOKEN. The pipeline uses npm Trusted Publishing (OIDC); no long-lived NPM_TOKEN is required.
One-time npmjs.com setup
- Sign in at npmjs.com as a maintainer of
@flowenapp/svelte-hcaptcha. - Open Packages → @flowenapp/svelte-hcaptcha → Settings → Trusted publishing.
- Under Select your publisher, choose GitLab CI/CD.
- Configure:
- Namespace (required):
flowenapp - Project (required):
svelte-hcaptcha - Top-level CI file path (required):
.gitlab-ci.yml - Environment name (optional): leave blank (the release job does not use a GitLab environment)
- Allowed actions:
npm publish(required for configurations created after May 2026)
- Namespace (required):
- Save the trusted publisher configuration.
- (Recommended) After verifying a successful CI publish, go to Settings → Publishing access and choose Require two-factor authentication and disallow tokens, then revoke any old automation tokens.
The CI job must run on GitLab.com shared runners (self-hosted runners are not supported). package.json must keep the correct repository.url for provenance:
"repository": {
"type": "git",
"url": "git+https://gitlab.com/flowenapp/svelte-hcaptcha.git"
}Manual publish (local)
For local publishes you still need normal npm authentication (login or token):
bun run package
npm publish --access public