'use client'; import { jsx as _jsx } from "react/jsx-runtime"; import { useEffect, useRef } from 'react'; const SCRIPT_SRC = 'https://challenges.cloudflare.com/turnstile/v0/api.js?render=explicit'; /** Loads the Turnstile script once, shared across all widget instances. */ function ensureScript() { if (typeof document === 'undefined') { return; } if (document.querySelector(`script[src="${SCRIPT_SRC}"]`)) { return; } const script = document.createElement('script'); script.src = SCRIPT_SRC; script.async = true; script.defer = true; document.head.appendChild(script); } /** * Cloudflare Turnstile widget — reusable across any form. Renders the challenge * and reports the token via onToken. The token must then be verified * server-side (see verifyTurnstile) before a submission is trusted. * * siteKey is a prop rather than an env var so all Turnstile config lives in one * place (SiteIntegrations), consistent with the plugin's panel-managed model. * The script is injected directly (no next/script dependency) so the widget * stays framework-agnostic. */ export function Turnstile({ onToken, siteKey, theme = 'auto' }) { const ref = useRef(null); const widgetId = useRef(null); useEffect(()=>{ if (!siteKey) { return; } ensureScript(); function render() { if (!ref.current || !window.turnstile || widgetId.current) { return; } widgetId.current = window.turnstile.render(ref.current, { callback: (token)=>onToken(token), 'error-callback': ()=>onToken(null), 'expired-callback': ()=>onToken(null), sitekey: siteKey, theme }); } render(); // Script may load after mount — retry briefly until ready. const interval = setInterval(render, 300); return ()=>clearInterval(interval); }, [ siteKey, theme, onToken ]); if (!siteKey) { return null; } return /*#__PURE__*/ _jsx("div", { ref: ref }); } //# sourceMappingURL=Turnstile.js.map