@novelcaptcha/react
v0.1.0
Published
React hooks for NovelCaptcha. Wraps @novelcaptcha/browser with useNovelCaptcha() and NovelCaptchaProvider.
Maintainers
Readme
@novelcaptcha/react
React hooks and a provider for NovelCaptcha. Wraps @novelcaptcha/browser so you don't manage script loading, StrictMode guards, or dismissal errors yourself.
npm install @novelcaptcha/react @novelcaptcha/browserUsage
import { NovelCaptchaProvider, useExecuteCaptcha } from "@novelcaptcha/react";
// At the top of your app
<NovelCaptchaProvider
sitekey="sk_..."
scriptUrl="https://your-host/api/api.js"
>
<App />
</NovelCaptchaProvider>;
// In a form component
function LoginForm() {
const submitCaptcha = useExecuteCaptcha();
async function onSubmit(e: React.FormEvent) {
e.preventDefault();
const { challengeKey } = await fetch("/api/login/challenge", { method: "POST" })
.then((r) => r.json());
const token = await submitCaptcha(challengeKey);
if (!token) return; // user dismissed the visible challenge
// ... submit with the token
}
}What you get
<NovelCaptchaProvider>— mounts the widget runtime once per subtree. Handles React StrictMode double-mount, provides load state to children.useNovelCaptcha()— returns{ ready, executing, error, execute }.executeis a stable callback.useExecuteCaptcha()— convenience wrapper. Returnsnullwhen the user dismisses a visible challenge, throws otherwise.
SSR
Import this on the server safely. All browser work happens inside useEffect, so <NovelCaptchaProvider> renders its children on the server without touching window or document. Load happens on hydration.
API surface (stable)
<NovelCaptchaProvider
sitekey={string} // required
scriptUrl?={string}
language?={string} // "ko" | "en" | ...
round?={boolean}
onReady?={() => void}
onLoadError?={(error) => void}
>const { ready, executing, error, execute } = useNovelCaptcha();const submitCaptcha = useExecuteCaptcha();
const token: string | null = await submitCaptcha(challengeKey, { timeoutMs?: number });License
MIT
