11import { useEffect , useRef } from 'react' ;
2- import { useSearchParams } from 'react-router-dom' ;
32
43const DEFAULT_SITE_KEY = import . meta. env . VITE_TURNSTILE_SITE_KEY as string ;
54
@@ -12,67 +11,105 @@ declare global {
1211
1312export default function TurnstileBridge ( ) {
1413 const containerRef = useRef < HTMLDivElement | null > ( null ) ;
15- const [ searchParams ] = useSearchParams ( ) ;
16-
17- const siteKey = searchParams . get ( 'sitekey' ) || DEFAULT_SITE_KEY ;
14+ const scriptLoadedRef = useRef ( false ) ;
1815
1916 useEffect ( ( ) => {
17+ const urlParams = new URLSearchParams ( window . location . search ) ;
18+ const siteKey = urlParams . get ( 'sitekey' ) || DEFAULT_SITE_KEY ;
19+
20+ if ( ! siteKey ) {
21+ console . error ( 'No sitekey provided' ) ;
22+ return ;
23+ }
24+
25+ if ( scriptLoadedRef . current ) {
26+ return ;
27+ }
28+
29+ const existingScript = document . querySelector ( 'script[src*="turnstile"]' ) ;
30+ if ( existingScript ) {
31+ scriptLoadedRef . current = true ;
32+ initializeTurnstile ( siteKey ) ;
33+ return ;
34+ }
35+
2036 const script = document . createElement ( 'script' ) ;
2137 script . src = 'https://challenges.cloudflare.com/turnstile/v0/api.js' ;
2238 script . async = true ;
2339 script . defer = true ;
40+
2441 script . onload = ( ) => {
25- // eslint-disable-next-line @typescript-eslint/no-explicit-any
26- const ts = ( window as any ) . turnstile as
27- | {
28- render : (
29- el : HTMLElement ,
30- opts : {
31- sitekey : string ;
32- callback ?: ( token : string ) => void ;
33- 'error-callback' ?: ( error : string ) => void ;
34- action ?: string ;
35- theme ?: 'light' | 'dark' | 'auto' ;
36- }
37- ) => void ;
38- }
39- | undefined ;
42+ scriptLoadedRef . current = true ;
43+ initializeTurnstile ( siteKey ) ;
44+ } ;
4045
41- if ( containerRef . current && ts ) {
42- ts . render ( containerRef . current , {
43- sitekey : siteKey ,
44- callback : ( token : string ) => {
45- window . location . href =
46- 'ethoraappreactnative://turnstile?token=' +
47- encodeURIComponent ( token ) ;
48- } ,
49- 'error-callback' : ( error : string ) => {
50- window . location . href =
51- 'ethoraappreactnative://turnstile?error=' +
52- encodeURIComponent ( String ( error ) ) ;
53- } ,
54- action : 'signup' ,
55- theme : 'light' ,
56- } ) ;
57- }
46+ script . onerror = ( ) => {
47+ console . error ( 'Failed to load Turnstile script' ) ;
5848 } ;
5949
6050 document . head . appendChild ( script ) ;
51+
6152 return ( ) => {
62- document . head . removeChild ( script ) ;
6353 } ;
6454 } , [ ] ) ;
6555
56+ const initializeTurnstile = ( siteKey : string ) => {
57+ if ( ! containerRef . current ) {
58+ console . error ( 'Container not found' ) ;
59+ return ;
60+ }
61+
62+ if ( typeof ( window as any ) . turnstile === 'undefined' ) {
63+ console . error ( 'Turnstile not available' ) ;
64+ return ;
65+ }
66+
67+ try {
68+ ( window as any ) . turnstile . render ( containerRef . current , {
69+ sitekey : siteKey ,
70+ callback : ( token : string ) => {
71+ try {
72+ window . location . href =
73+ 'ethoraappreactnative://turnstile?token=' +
74+ encodeURIComponent ( token ) ;
75+ } catch ( err ) {
76+ console . error ( 'Error redirecting with token:' , err ) ;
77+ }
78+ } ,
79+ 'error-callback' : ( error : string ) => {
80+ try {
81+ window . location . href =
82+ 'ethoraappreactnative://turnstile?error=' +
83+ encodeURIComponent ( String ( error ) ) ;
84+ } catch ( err ) {
85+ console . error ( 'Error redirecting with error:' , err ) ;
86+ }
87+ } ,
88+ action : 'signup' ,
89+ theme : 'light' ,
90+ } ) ;
91+ } catch ( err ) {
92+ console . error ( 'Error initializing Turnstile:' , err ) ;
93+ }
94+ } ;
95+
6696 return (
6797 < div
6898 style = { {
6999 minHeight : '100vh' ,
70100 display : 'flex' ,
71101 alignItems : 'center' ,
72102 justifyContent : 'center' ,
103+ backgroundColor : '#f5f5f5' ,
73104 } }
74105 >
75- < div ref = { containerRef } />
106+ < div
107+ ref = { containerRef }
108+ style = { {
109+ minHeight : '65px' ,
110+ minWidth : '300px' ,
111+ } }
112+ />
76113 </ div >
77114 ) ;
78- }
115+ }
0 commit comments