{"id":18836762,"url":"https://github.com/hcaptcha/react-hcaptcha","last_synced_at":"2026-01-16T08:00:17.245Z","repository":{"id":37466645,"uuid":"149192539","full_name":"hCaptcha/react-hcaptcha","owner":"hCaptcha","description":"hCaptcha Component Library for ReactJS and Preact","archived":false,"fork":false,"pushed_at":"2026-01-12T17:48:08.000Z","size":1475,"stargazers_count":506,"open_issues_count":12,"forks_count":136,"subscribers_count":42,"default_branch":"master","last_synced_at":"2026-01-12T22:12:36.000Z","etag":null,"topics":["captcha","hcaptcha","react","reactjs"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hCaptcha.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2018-09-17T21:50:31.000Z","updated_at":"2026-01-12T17:45:09.000Z","dependencies_parsed_at":"2023-02-02T23:46:45.233Z","dependency_job_id":"0be7d990-79d8-48b9-a985-84fbba0ec402","html_url":"https://github.com/hCaptcha/react-hcaptcha","commit_stats":{"total_commits":204,"total_committers":25,"mean_commits":8.16,"dds":0.7205882352941176,"last_synced_commit":"2f8d4d9152261955acbc44118447fb7b481a1825"},"previous_names":[],"tags_count":55,"template":false,"template_full_name":null,"purl":"pkg:github/hCaptcha/react-hcaptcha","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hCaptcha%2Freact-hcaptcha","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hCaptcha%2Freact-hcaptcha/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hCaptcha%2Freact-hcaptcha/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hCaptcha%2Freact-hcaptcha/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hCaptcha","download_url":"https://codeload.github.com/hCaptcha/react-hcaptcha/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hCaptcha%2Freact-hcaptcha/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28478047,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-16T06:30:42.265Z","status":"ssl_error","status_checked_at":"2026-01-16T06:30:16.248Z","response_time":107,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["captcha","hcaptcha","react","reactjs"],"created_at":"2024-11-08T02:31:53.898Z","updated_at":"2026-01-16T08:00:17.162Z","avatar_url":"https://github.com/hCaptcha.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# React hCaptcha Component Library\n\n\nhCaptcha Component Library for ReactJS.\n\n[hCaptcha](https://www.hcaptcha.com) is a drop-replacement for reCAPTCHA that protects user privacy.\n\nSign up at [hCaptcha](https://www.hcaptcha.com) to get your sitekey today. **You need a sitekey to use this library.**\n\n*Also compatible with Preact.*\n\n1. [Installation](#installation)\n2. [References](#references)\n3. [Debugging](#debugging)\n4. [Contributing](#contributing)\n\n## Installation\n\nYou can install this library via npm with:\n\n```\nnpm install @hcaptcha/react-hcaptcha --save\n```\n\n### Implementation\nThe two requirements for usage are the `sitekey` [prop](#props) and a `parent component` such as a `\u003cform /\u003e`. The component will automatically include and load the\nhCaptcha API library and append it to the parent component. This is designed for ease of use with the hCaptcha API!\n\n#### Standard\n\n```js\nimport HCaptcha from '@hcaptcha/react-hcaptcha';\n\n\u003cFormComponent\u003e\n    \u003cHCaptcha\n      sitekey=\"your-sitekey\"\n      onVerify={(token,ekey) =\u003e handleVerificationSuccess(token, ekey)}\n    /\u003e\n\u003c/FormComponent\u003e\n```\n\n#### Programmatic\nIn the event you want to call the hCaptcha client API directly, you can do so by using the hook `useRef` and waiting for `onLoad` to be called. By waiting for `onLoad` the hCaptcha API will be ready and the hCaptcha client will have been setup. See the following example:\n\n```js\nimport { useEffect, useRef, useState } from \"react\";\nimport HCaptcha from \"@hcaptcha/react-hcaptcha\";\n\nexport default function Form() {\n  const [token, setToken] = useState(null);\n  const captchaRef = useRef(null);\n\n  const onLoad = () =\u003e {\n    // this reaches out to the hCaptcha JS API and runs the\n    // execute function on it. you can use other functions as\n    // documented here:\n    // https://docs.hcaptcha.com/configuration#jsapi\n    captchaRef.current.execute();\n  };\n\n  useEffect(() =\u003e {\n\n    if (token)\n      console.log(`hCaptcha Token: ${token}`);\n\n  }, [token]);\n\n  return (\n    \u003cform\u003e\n      \u003cHCaptcha\n        sitekey=\"your-sitekey\"\n        onLoad={onLoad}\n        onVerify={setToken}\n        ref={captchaRef}\n      /\u003e\n    \u003c/form\u003e\n  );\n}\n```\n\n**Typescript Support** \\\nIf you want to reassign the component name, you could consider making a util that imports the component, then re-exports it as a default.\n\n```ts\n// utils/captcha.ts\nimport HCaptcha from '@hcaptcha/react-hcaptcha';\nexport default HCaptcha;\n\n// MyFormComponent.tsx\nimport { default as RenamedCaptcha } from '../utils/captcha';\n\u003cFormComponent\u003e\n  \u003cRenamedCaptcha sitekey=\"your-sitekey\" /\u003e\n\u003c/FormComponent\u003e\n```\n\n#### Provider/Hook Pattern\n\nYou can also use the Provider/Hook pattern:\n\n```js\nimport { HCaptchaProvider, useHCaptcha } from '@hcaptcha/react-hcaptcha';\n\nfunction App() {\n  return (\n    \u003cHCaptchaProvider sitekey=\"your-sitekey\"\u003e\n      \u003cForm /\u003e\n    \u003c/HCaptchaProvider\u003e\n  );\n}\n\nfunction Form() {\n  const { ready, token, executeInstance } = useHCaptcha();\n\n  const onSubmit = async () =\u003e {\n    const response = await executeInstance();\n    console.log(\"Token:\", response);\n  };\n\n  return \u003cbutton onClick={onSubmit} disabled={!ready}\u003eSubmit\u003c/button\u003e;\n}\n```\n\n##### Provider Props\n\n|Name|Values/Type|Required|Default|Description|\n|---|---|---|---|---|\n|`sitekey`|String|**Yes**|`-`|Your hCaptcha sitekey.|\n|`size`|String (normal, compact, invisible)|No|`normal`|The size of the hCaptcha widget.|\n|`theme`|String (light, dark)|No|`light`|The theme of the widget.|\n|`rqdata`|String|No|`-`|See enterprise docs.|\n|`languageOverride`|String|No|`-`|Language override (ISO 639-2 code).|\n|`onVerify`|Function|No|`-`|Callback when captcha is verified.|\n|`onError`|Function|No|`-`|Callback when an error occurs.|\n\n##### useHCaptcha Hook\n\nReturns an object with:\n\n|Property|Type|Description|\n|---|---|---|\n|`executeInstance`|Function|Execute hCaptcha programmatically. Returns a Promise that resolve with a new token.|\n|`resetInstance`|Function|Reset the hCaptcha client instance.|\n|`ready`|Boolean|Whether hCaptcha is loaded and ready.|\n|`token`|String \\| null|Current hCaptcha token (if verified).|\n|`error`|Error \\| null|Any error that occurred.|\n|`sitekey`|String|The hCaptcha sitekey.|\n\n#### Advanced\n\nIn most real-world implementations, you'll probably be using a form library such as [Formik](https://github.com/jaredpalmer/formik) or [React Hook Form](https://github.com/react-hook-form/react-hook-form).\n\nIn these instances, you'll most likely want to use `ref` to handle the callbacks as well as handle field-level validation of a `captcha` field. For an example of this, you can view this [CodeSandbox](https://codesandbox.io/s/react-hcaptchaform-example-forked-ngxge?file=/src/Form.jsx).  This `ref` will point to an instance of the [hCaptcha API](https://docs.hcaptcha.com/configuration#jsapi) where can you interact directly with it.\n\n#### Passing in fields like `rqdata` to `execute()`\n\nPassing an object into the `execute(yourObj)` call will send it through to the underlying JS API. This enables support for Enterprise features like `rqdata`. A simple example is below:\n\n```\nconst {sitekey, rqdata} = props;\nconst captchaRef = React.useRef\u003cHCaptcha\u003e(null);\n\nconst onLoad = () =\u003e {\n  const executePayload = {};\n  if (rqdata) {\n    executePayload['rqdata'] = rqdata;\n  }\n  captchaRef.current?.execute(executePayload);\n};\n\nreturn \u003cHCaptcha ref={captchaRef} onLoad={onLoad} sitekey={sitekey} {...props} /\u003e;\n```\n\n### References\n\n#### Props\n\n|Name|Values/Type|Required|Default|Description|\n|---|---|---|---|---|\n|`sitekey`|String|**Yes**|`-`|This is your sitekey, this allows you to load captcha. If you need a sitekey, please visit [hCaptcha](https://www.hcaptcha.com), and sign up to get your sitekey.|\n|`size`|String (normal, compact, invisible)|No|`normal`|This specifies the \"size\" of the component. hCaptcha allows you to decide how big the component will appear on render, this always defaults to normal.|\n|`theme`|String (light, dark, contrast) or Object|No|`light`|hCaptcha supports both a light and dark theme. Defaults to light. Takes Object if custom theme is used.|\n|`tabindex`|Integer|No|`0`|Set the tabindex of the widget and popup. When appropriate, this can make navigation of your site more intuitive.|\n|`languageOverride`|String (ISO 639-2 code)|No|`auto`|hCaptcha auto-detects language via the user's browser. This overrides that to set a default UI language. See [language codes](https://hcaptcha.com/docs/languages).|\n|`reCaptchaCompat`|Boolean|No|`true`|Disable drop-in replacement for reCAPTCHA with `false` to prevent hCaptcha from injecting into `window.grecaptcha`.|\n|`id`|String|No|`random id`|Manually set the ID of the hCaptcha component. Make sure each hCaptcha component generated on a single page has its own unique ID when using this prop.|\n|`apihost`|String|No|`-`|See enterprise docs.|\n|`assethost`|String|No|`-`|See enterprise docs.|\n|`endpoint`|String|No|`-`|See enterprise docs.|\n|`host`|String|No|`-`|See enterprise docs.|\n|`imghost`|String|No|`-`|See enterprise docs.|\n|`reportapi`|String|No|`-`|See enterprise docs.|\n|`sentry`|Boolean|No|`true`|See enterprise docs.|\n|`userJourneys`|Boolean|No|`false`|See enterprise docs.|\n|`secureApi`|Boolean|No|`-`|See enterprise docs.|\n|`scriptSource`|String|No|`-`|See enterprise docs.|\n| `cleanup`         | Boolean     | No       | `true`          | Remove script tag after setup.|\n|`custom`|Boolean|No|`-`|Custom theme: see enterprise docs.|\n|`loadAsync`|Boolean|No|`true`|Set if the script should be loaded asynchronously.|\n|`scriptLocation`|Element|No|`document.head`| Location of where to append the script tag. Make sure to add it to an area that will persist to prevent loading multiple times in the same document view. Note: If `null` is provided, the `document.head` will be used.|\n\n#### Events\n\n|Event|Params|Description|\n|---|---|---|\n|`onError`|`err`|When an error occurs. Component will reset immediately after an error.|\n|`onVerify`|`token, eKey`|When challenge is completed. The response `token` and an `eKey` (session id) are passed along.|\n|`onExpire`|-|When the current token expires.|\n|`onLoad`|-|When the hCaptcha API loads.|\n|`onReady`|-|When the hCaptcha is ready to be used.|\n|`onOpen`|-|When the user display of a challenge starts.|\n|`onClose`|-|When the user dismisses a challenge.|\n|`onChalExpired`|-|When the user display of a challenge times out with no answer.|\n\n#### Methods\n\n|Method|Description|\n|---|---|\n|`execute()`|Programmatically trigger a challenge request. Additionally, this method can be run asynchronously and returns a promise with the `token` and `eKey` when the challenge is completed.|\n|`getRespKey()`|Get the current challenge reference ID|\n|`getResponse()`|Get the current challenge response token from completed challenge|\n|`resetCaptcha()`|Reset the current challenge|\n|`setData()`|See enterprise docs.|\n\n\n\u003e **Note** \\\n\u003e Make sure to reset the hCaptcha state when you submit your form by calling the method `.resetCaptcha` on your hCaptcha React Component! Passcodes are one-time use, so if your user submits the same passcode twice then it will be rejected by the server the second time.\n\nPlease refer to the demo for examples of basic usage and an invisible hCaptcha.\n\nAlternatively, see [this sandbox code](https://codesandbox.io/s/react-hcaptchaform-example-invisible-f7ekt) for a quick form example of invisible hCaptcha on a form submit button.\n\nPlease note that \"invisible\" simply means that no hCaptcha button will be rendered. Whether a challenge shows up will depend on the sitekey difficulty level. Note to hCaptcha Enterprise ([BotStop](https://www.botstop.com)) users: select \"Passive\" or \"99.9% Passive\" modes to get this No-CAPTCHA behavior.\n\n\n\n\n### Debugging\n\n1. #### Invalid hCaptcha Id: \u003chcaptcha_id\u003e\n    This issue generally occurs when the component is re-rendered causing the current `useRef` to become stale, meaning the `ref` being used is no longer available in the DOM.\n\n\n2. #### Make sure you don't double-import the api.js script\n    Importing the JS SDK twice can cause unpredictable behavior, so don't do a direct import separately if you are using react-hcaptcha.\n\n3. #### Make sure you are using `reCaptchaCompat=false` if you have the reCAPTCHA JS loaded on the same page.\n    The hCaptcha \"compatibility mode\" will interfere with reCAPTCHA, as it adds properties with the same name. If for any reason you are running both hCaptcha and reCAPTCHA in parallel (we recommend only running hCaptcha) then please disable our compatibility mode.\n\n\n### Sentry\n\nIf the `sentry` flag is enabled, the upstream `hcaptcha-loader` package expects the Sentry SDK, version 8.x or later.\n\nIf you have an older `@sentry/browser` client version on your site, it may take precedence over the bundled version. In this case you may see a console error like \"g.setPropagationContext is not a function\" due to the hcaptcha-loader trying to call methods only available on newer Sentry clients.\n\nTo resolve this, update the version of the Sentry client you are including on your site to 8.x or higher.\n\nYou can avoid this issue by setting the `sentry` prop to `false`.\n\n\n### Handling SDK Errors\n\nIf the JS SDK fails to load, the `onError` callback will be invoked with `script-error` argument.\n\nThis will be rare, but could happen in the event you are testing offline, or have enabled a firewall that does not allow outbound connections to the asset hosts hCaptcha uses.\n\n---\n### Contributing\n\n#### Scripts\n\n* `pnpm run start` - will start the demo app with hot reload\n* `pnpm run test` - will test the library: unit tests\n* `pnpm --filter @hcaptcha-react/lib run combile:build` - will build the production version\n\n\n#### Environment Variables for Development\nFor developing react-hcaptcha itself, create a `.env` in the root directory. `.env.example` shows the variables that can be set. If this file is not present, build variables default to a production configuration.\n\n\n#### Publishing\n\nTo publish a new version, follow the next steps:\n1. Bump the version in `package.json`\n2. Create a [Github Release](https://docs.github.com/en/free-pro-team@latest/github/administering-a-repository/managing-releases-in-a-repository#creating-a-release) with version from step 1 **without** a prefix such as `v` (e.g. `1.0.3`)\n  * `publish` workflow will be triggered which will: build, test and deploy the package to the [npm @hcaptcha/react-hcaptcha](https://www.npmjs.com/package/@hcaptcha/react-hcaptcha).\n\n\n#### Running locally for development\n\nPlease see: [Local Development Notes](https://docs.hcaptcha.com/#localdev).\n\nSummary:\n\n```\nsudo echo \"127.0.0.1 fakelocal.com\" \u003e\u003e /private/etc/hosts\nnpm start -- --disable-host-check\n```\n\nopen [http://fakelocal.com:9000](http://fakelocal.com:9000) to start the example.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhcaptcha%2Freact-hcaptcha","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhcaptcha%2Freact-hcaptcha","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhcaptcha%2Freact-hcaptcha/lists"}