1
1
import React from 'react' ;
2
2
import {
3
+ useRef ,
3
4
useMemo ,
4
5
useState ,
5
6
useEffect ,
@@ -18,7 +19,7 @@ enum GoogleRecaptchaError {
18
19
}
19
20
20
21
interface IGoogleReCaptchaProviderProps {
21
- reCaptchaKey ? : string ;
22
+ reCaptchaKey : string ;
22
23
language ?: string ;
23
24
useRecaptchaNet ?: boolean ;
24
25
useEnterprise ?: boolean ;
@@ -28,6 +29,18 @@ interface IGoogleReCaptchaProviderProps {
28
29
async ?: boolean ;
29
30
appendTo ?: 'head' | 'body' ;
30
31
id ?: string ;
32
+ onLoadCallbackName ?: string ;
33
+ } ;
34
+ inlineBadgeId ?: string | HTMLElement ;
35
+ parameters ?: {
36
+ sitekey ?: string ;
37
+ badge ?: string ;
38
+ theme ?: string ;
39
+ size ?: string ;
40
+ tabindex ?: number ;
41
+ callback ?: ( ) => void ;
42
+ expiredCallback ?: ( ) => void ;
43
+ errorCallback ?: ( ) => void ;
31
44
} ;
32
45
children : ReactNode ;
33
46
}
@@ -53,11 +66,14 @@ export function GoogleReCaptchaProvider({
53
66
useRecaptchaNet = false ,
54
67
scriptProps,
55
68
language,
69
+ inlineBadgeId,
70
+ parameters = { } ,
56
71
children
57
72
} : IGoogleReCaptchaProviderProps ) {
58
73
const [ greCaptchaInstance , setGreCaptchaInstance ] = useState < null | {
59
74
execute : Function ;
60
75
} > ( null ) ;
76
+ const clientId = useRef < number | string > ( reCaptchaKey ) ;
61
77
62
78
useEffect ( ( ) => {
63
79
if ( ! reCaptchaKey ) {
@@ -69,6 +85,22 @@ export function GoogleReCaptchaProvider({
69
85
}
70
86
71
87
const scriptId = scriptProps ?. id || 'google-recaptcha-v3' ;
88
+ const onLoadCallbackName = scriptProps ?. onLoadCallbackName || 'onRecaptchaLoadCallback' ;
89
+
90
+ ( ( window as unknown ) as { [ key : string ] : ( ) => void } ) [ onLoadCallbackName ] = ( ) => {
91
+ /* eslint-disable @typescript-eslint/no-explicit-any */
92
+ const grecaptcha = useEnterprise
93
+ ? ( window as any ) . grecaptcha . enterprise
94
+ : ( window as any ) . grecaptcha ;
95
+
96
+ const params = {
97
+ badge : 'inline' ,
98
+ size : 'invisible' ,
99
+ sitekey : reCaptchaKey ,
100
+ ...( parameters || { } )
101
+ } ;
102
+ clientId . current = grecaptcha . render ( inlineBadgeId , params ) ;
103
+ } ;
72
104
73
105
const onLoad = ( ) => {
74
106
if ( ! window || ! ( window as any ) . grecaptcha ) {
@@ -93,7 +125,8 @@ export function GoogleReCaptchaProvider({
93
125
} ;
94
126
95
127
injectGoogleReCaptchaScript ( {
96
- reCaptchaKey,
128
+ render : inlineBadgeId ? 'explicit' : reCaptchaKey ,
129
+ onLoadCallbackName,
97
130
useEnterprise,
98
131
useRecaptchaNet,
99
132
scriptProps,
@@ -115,18 +148,17 @@ export function GoogleReCaptchaProvider({
115
148
) ;
116
149
}
117
150
118
- const result = await greCaptchaInstance . execute ( reCaptchaKey , { action } ) ;
119
-
120
- return result ;
151
+ return await greCaptchaInstance . execute ( clientId . current , { action } ) ;
121
152
} ,
122
- [ greCaptchaInstance ]
153
+ [ greCaptchaInstance , clientId ]
123
154
) ;
124
155
125
156
const googleReCaptchaContextValue = useMemo (
126
157
( ) => ( {
127
- executeRecaptcha : greCaptchaInstance ? executeRecaptcha : undefined
158
+ executeRecaptcha : greCaptchaInstance ? executeRecaptcha : undefined ,
159
+ inlineBadgeId,
128
160
} ) ,
129
- [ executeRecaptcha , greCaptchaInstance ]
161
+ [ executeRecaptcha , greCaptchaInstance , inlineBadgeId ]
130
162
) ;
131
163
132
164
return (
0 commit comments