Skip to content

Commit 006c31f

Browse files
authored
Merge pull request #1 from ramirezcgn/inline-badge
Inline badge
2 parents 8110bb6 + 2c88eb0 commit 006c31f

File tree

2 files changed

+51
-15
lines changed

2 files changed

+51
-15
lines changed

src/google-recaptcha-provider.tsx

Lines changed: 40 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import React from 'react';
22
import {
3+
useRef,
34
useMemo,
45
useState,
56
useEffect,
@@ -18,7 +19,7 @@ enum GoogleRecaptchaError {
1819
}
1920

2021
interface IGoogleReCaptchaProviderProps {
21-
reCaptchaKey?: string;
22+
reCaptchaKey: string;
2223
language?: string;
2324
useRecaptchaNet?: boolean;
2425
useEnterprise?: boolean;
@@ -28,6 +29,18 @@ interface IGoogleReCaptchaProviderProps {
2829
async?: boolean;
2930
appendTo?: 'head' | 'body';
3031
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;
3144
};
3245
children: ReactNode;
3346
}
@@ -53,11 +66,14 @@ export function GoogleReCaptchaProvider({
5366
useRecaptchaNet = false,
5467
scriptProps,
5568
language,
69+
inlineBadgeId,
70+
parameters = {},
5671
children
5772
}: IGoogleReCaptchaProviderProps) {
5873
const [greCaptchaInstance, setGreCaptchaInstance] = useState<null | {
5974
execute: Function;
6075
}>(null);
76+
const clientId = useRef<number | string>(reCaptchaKey);
6177

6278
useEffect(() => {
6379
if (!reCaptchaKey) {
@@ -69,6 +85,22 @@ export function GoogleReCaptchaProvider({
6985
}
7086

7187
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+
};
72104

73105
const onLoad = () => {
74106
if (!window || !(window as any).grecaptcha) {
@@ -93,7 +125,8 @@ export function GoogleReCaptchaProvider({
93125
};
94126

95127
injectGoogleReCaptchaScript({
96-
reCaptchaKey,
128+
render: inlineBadgeId ? 'explicit' : reCaptchaKey,
129+
onLoadCallbackName,
97130
useEnterprise,
98131
useRecaptchaNet,
99132
scriptProps,
@@ -115,18 +148,17 @@ export function GoogleReCaptchaProvider({
115148
);
116149
}
117150

118-
const result = await greCaptchaInstance.execute(reCaptchaKey, { action });
119-
120-
return result;
151+
return await greCaptchaInstance.execute(clientId.current, { action });
121152
},
122-
[greCaptchaInstance]
153+
[greCaptchaInstance, clientId]
123154
);
124155

125156
const googleReCaptchaContextValue = useMemo(
126157
() => ({
127-
executeRecaptcha: greCaptchaInstance ? executeRecaptcha : undefined
158+
executeRecaptcha: greCaptchaInstance ? executeRecaptcha : undefined,
159+
inlineBadgeId,
128160
}),
129-
[executeRecaptcha, greCaptchaInstance]
161+
[executeRecaptcha, greCaptchaInstance, inlineBadgeId]
130162
);
131163

132164
return (

src/utils.ts

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
interface InjectGoogleReCaptchaScriptParams {
2-
reCaptchaKey: string;
1+
interface IInjectGoogleReCaptchaScriptParams {
2+
render: string;
3+
onLoadCallbackName: string;
34
useRecaptchaNet: boolean;
45
useEnterprise: boolean;
56
onLoad: () => void;
@@ -38,7 +39,7 @@ const generateGoogleRecaptchaSrc = ({
3839
*/
3940
const cleanGstaticRecaptchaScript = () => {
4041
const script = document.querySelector(
41-
`script[src^='https://www.gstatic.com/recaptcha/releases']`
42+
'script[src^="https://www.gstatic.com/recaptcha/releases"]'
4243
);
4344

4445
if (script) {
@@ -83,7 +84,8 @@ export const cleanGoogleRecaptcha = (scriptId: string) => {
8384
* @returns
8485
*/
8586
export const injectGoogleReCaptchaScript = ({
86-
reCaptchaKey,
87+
render,
88+
onLoadCallbackName,
8789
language,
8890
onLoad,
8991
useRecaptchaNet,
@@ -93,9 +95,9 @@ export const injectGoogleReCaptchaScript = ({
9395
defer = false,
9496
async = false,
9597
id = '',
96-
appendTo = undefined
98+
appendTo
9799
} = {}
98-
}: InjectGoogleReCaptchaScriptParams) => {
100+
}: IInjectGoogleReCaptchaScriptParams) => {
99101
const scriptId = id || 'google-recaptcha-v3';
100102

101103
// Script has already been injected, just call onLoad and does othing else
@@ -114,7 +116,9 @@ export const injectGoogleReCaptchaScript = ({
114116
});
115117
const js = document.createElement('script');
116118
js.id = scriptId;
117-
js.src = `${googleRecaptchaSrc}?render=${reCaptchaKey}${
119+
js.src = `${googleRecaptchaSrc}?render=${render}${
120+
render === 'explicit' ? `&onload=${onLoadCallbackName}` : ''
121+
}${
118122
language ? `&hl=${language}` : ''
119123
}`;
120124

0 commit comments

Comments
 (0)