Giter VIP home page Giter VIP logo

react-google-recaptcha-v3's Introduction

React Google Recaptcha V3

React library for integrating Google ReCaptcha V3 to your App.

npm package Code style type definition

Install

npm install react-google-recaptcha-v3

Usage

Provide Recaptcha Key

To use react-google-recaptcha-v3, you need to create a recaptcha key for your domain, you can get one from here.

Enterprise

When you enable to use the enterprise version, you must create new keys. These keys will replace any Site Keys you created in reCAPTCHA. Check the migration guide.

To work properly, you must select the Integration type to be Scoring since is equivalent to the reCAPTCHA v3.

The complete documentation to the enterprise version you can see here.

Components

GoogleReCaptchaProvider

react-google-recaptcha-v3 provides a GoogleReCaptchaProvider provider component that should be used to wrap around your components.

GoogleReCaptchaProvider's responsibility is to load the necessary reCaptcha script and provide access to reCaptcha to the rest of your application.

Usually, your application only needs one provider. You should place it as high as possible in your React tree. It's to make sure you only have one instance of Google Recaptcha per page and it doesn't reload unecessarily when your components re-rendered.

Same thing applied when you use this library with framework such as Next.js or React Router and only want to include the script on a single page. Try to make sure you only have one instance of the provider on a React tree and to place it as high (on the tree) as possible.

Props Type Default Required? Note
reCaptchaKey String Yes Your recaptcha key, get one from here
scriptProps Object No You can customize the injected script tag with this prop. It allows you to add async, defer, nonce attributes to the script tag. You can also control whether the injected script will be added to the document body or head with appendTo attribute.
language String No optional prop to support different languages that is supported by Google Recaptcha. https://developers.google.com/recaptcha/docs/language
useRecaptchaNet Boolean false No The provider also provide the prop useRecaptchaNet to load script from recaptcha.net: https://developers.google.com/recaptcha/docs/faq#can-i-use-recaptcha-globally
useEnterprise Boolean false No Enterprise option
container.element String HTMLElement No Container ID where the recaptcha badge will be rendered
container.parameters Object No Configuration for the inline badge (See google recaptcha docs)
import { GoogleReCaptchaProvider } from 'react-google-recaptcha-v3';

ReactDom.render(
  <GoogleReCaptchaProvider
    reCaptchaKey="[Your recaptcha key]"
    language="[optional_language]"
    useRecaptchaNet="[optional_boolean_value]"
    useEnterprise="[optional_boolean_value]"
    scriptProps={{
      async: false, // optional, default to false,
      defer: false, // optional, default to false
      appendTo: 'head', // optional, default to "head", can be "head" or "body",
      nonce: undefined // optional, default undefined
    }}
    container={{ // optional to render inside custom element
      element: "[required_id_or_htmlelement]",
      parameters: {
        badge: '[inline|bottomright|bottomleft]', // optional, default undefined
        theme: 'dark', // optional, default undefined
      }
    }}
  >
    <YourApp />
  </GoogleReCaptchaProvider>,
  document.getElementById('app')
);

There are three ways to trigger the recaptcha validation: using the GoogleReCaptcha component, wrapping your component with the HOC withGoogleReCaptcha, or using the custom hook useGoogleReCaptcha.

GoogleReCaptcha

GoogleRecaptcha is a react component that can be used in your app to trigger the validation. It provides a prop onVerify, which will be called once the verify is done successfully, also supports a prop refreshReCaptcha which supports any type of value and is used to force recaptcha to revalidate (you can use a timestamp updated after every submit), there is an example below.

import {
  GoogleReCaptchaProvider,
  GoogleReCaptcha
} from 'react-google-recaptcha-v3';

ReactDom.render(
  <GoogleReCaptchaProvider reCaptchaKey="[Your recaptcha key]">
    <GoogleReCaptcha onVerify={handleVerify} />
  </GoogleReCaptchaProvider>,
  document.getElementById('app')
);
// IMPORTANT NOTES: The `GoogleReCaptcha` component is a wrapper around `useGoogleRecaptcha` hook and use `useEffect` to run the verification.
// It's important that you understand how React hooks work to use it properly.
// Avoid using inline function for the `onVerify` props as it can possibly cause the verify function to run continously.
// To avoid that problem, you can use a memoized function provided by `React.useCallback` or a class method
// The code below is an example that inline function can result in an infinite loop and the verify function runs continously:

const MyComponent: FC = () => {
  const [token, setToken] = useState();

  return (
    <div>
      <GoogleReCaptcha
        onVerify={token => {
          setToken(token);
        }}
      />
    </div>
  );
};
// Example of refreshReCaptcha option:

const MyComponent: FC = () => {
  const [token, setToken] = useState();
  const [refreshReCaptcha, setRefreshReCaptcha] = useState(false);

  const onVerify = useCallback((token) => {
    setToken(token);
  });

  const doSomething = () => {
    /* do something like submit a form and then refresh recaptcha */
    setRefreshReCaptcha(r => !r);
  }

  return (
    <div>
      <GoogleReCaptcha
        onVerify={onVerify}
        refreshReCaptcha={refreshReCaptcha}
      />
      <button onClick={doSomething}>
        Do Something
      </button>
    </div>
  );
};

React Hook: useGoogleReCaptcha (recommended approach)

If you prefer a React Hook approach over the old good Higher Order Component, you can choose to use the custom hook useGoogleReCaptcha over the HOC withGoogleReCaptcha.

The executeRecaptcha function returned from the hook can be undefined when the recaptcha script has not been successfully loaded. You can do a null check to see if it's available or not.

How to use the hook:

import {
  GoogleReCaptchaProvider,
  useGoogleReCaptcha
} from 'react-google-recaptcha-v3';

const YourReCaptchaComponent = () => {
  const { executeRecaptcha } = useGoogleReCaptcha();

  // Create an event handler so you can call the verification on button click event or form submit
  const handleReCaptchaVerify = useCallback(async () => {
    if (!executeRecaptcha) {
      console.log('Execute recaptcha not yet available');
      return;
    }

    const token = await executeRecaptcha('yourAction');
    // Do whatever you want with the token
  }, [executeRecaptcha]);

  // You can use useEffect to trigger the verification as soon as the component being loaded
  useEffect(() => {
    handleReCaptchaVerify();
  }, [handleReCaptchaVerify]);

  return <button onClick={handleReCaptchaVerify}>Verify recaptcha</button>;
};

ReactDom.render(
  <GoogleReCaptchaProvider reCaptchaKey="[Your recaptcha key]">
    <YourReCaptchaComponent />
  </GoogleReCaptchaProvider>,
  document.getElementById('app')
);

withGoogleReCaptcha

GoogleRecaptcha is a HOC (higher order component) that can be used to integrate reCaptcha validation with your component and trigger the validation programmatically. It inject the wrapped component with googleReCaptchaProps object.

The object contains the executeRecaptcha function that can be called to validate the user action.

You are recommended to use the custom hook useGoogleReCaptcha over the HOC whenever you can. The HOC can be removed in future version.

import {
  GoogleReCaptchaProvider,
  withGoogleReCaptcha
} from 'react-google-recaptcha-v3';

class ReCaptchaComponent extends Component<{}> {
  handleVerifyRecaptcha = async () => {
    const { executeRecaptcha } = (this.props as IWithGoogleReCaptchaProps)
      .googleReCaptchaProps;

    if (!executeRecaptcha) {
      console.log('Recaptcha has not been loaded');

      return;
    }

    const token = await executeRecaptcha('homepage');
  };

  render() {
    return (
      <div>
        <button onClick={this.handleVerifyRecaptcha}>Verify Recaptcha</button>
      </div>
    );
  }
}

export const WithGoogleRecaptchaExample =
  withGoogleReCaptcha(ReCaptchaComponent);

ReactDom.render(
  <GoogleReCaptchaProvider reCaptchaKey="[Your recaptcha key]">
    <WithGoogleRecaptchaExample />
  </GoogleReCaptchaProvider>,
  document.getElementById('app')
);

Example

An example of how to use these two hooks can found inside the example folder. You will need to provide an .env file if you want to run it on your own machine.

RECAPTCHA_KEY=[YOUR_RECAPTCHA_KEY]

react-google-recaptcha-v3's People

Contributors

arcturus5404 avatar bbenoist avatar biswaviraj avatar chentsulin avatar crhistianramirez avatar dependabot[bot] avatar difuks avatar fmsthird avatar igelineau avatar italosa avatar kibbewater avatar liviuzachin avatar luangb avatar maximushaximus avatar neenus avatar nmalyarsky avatar ramirezcgn avatar renansigolo avatar renomureza avatar salvoravida avatar silviu-marian avatar t49tran avatar ypresto avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

react-google-recaptcha-v3's Issues

Feature Request: Possibility to hide banner

.grecaptcha-badge { visibility: hidden; }
hides the banner and is allowed as long

This site is protected by reCAPTCHA and the Google
    <a href="https://policies.google.com/privacy">Privacy Policy</a> and
    <a href="https://policies.google.com/terms">Terms of Service</a> apply.

is provided on the form (https://developers.google.com/recaptcha/docs/faq)

I'd love to see this feature with a invisible=true || false flag. Should be fine, when referencing the faq in the docs

Customize script url

Hello everyone.
Is there any reason why still didn't provided prop like customApiUrl or something to handle api2 of invisible recaptcha?
Thanx (:

using recaptcha v3 from a react-native-webview is not working

when this component is used on a website it works very well and tokens are generated without issues, but when that same website is loaded in a react-native-webview (community) the initial call (from ) doesn't get through at all, and we don't get a token back.

I tried adding a nonce value to the embed string and adding csp to the site headers and no luck.
any ideas?

Expand documentation for `executeRecaptcha`

Hello @t49tran. Thank you for making this library!
I think documentation can be improved by adding information on non-successful cases for executeRecaptcha.

Currently, README contains just this line:

const token = await this.props.googleReCaptchaProps.executeRecaptcha('homepage')

^ it's unclear what will happen if bot sends a request. Will it throw? Will it return null? Or empty string? Or an object with error data?

In my own experiments, sometimes it throws and sometimes an empty token is returned 🤔

Unfortunately, the official docs does not provide this information either: https://developers.google.com/recaptcha/docs/invisible

how to reset recaptcha ?

I installed the module in react Single Page Apps, the problem is I need to use the recaptcha only on 2 pages (e.g register and contact). but the token only generated once .

executeRecaptcha never resolve

If recaptcha token is not specified executeRecaptcha() promise doesn't resolve or reject. In the example below token or error is never printed.

try {
  const recaptchaToken = await executeRecaptcha('signup_modal');
  console.log('token', recaptchaToken);
} catch (error) {
  console.log(error)
}

This behavior can be described by the following example code.

const simple = async () => {
  console.log('start')
  await new Promise(resolve => {})
  console.log('done.')
}

I'm using "react-google-recaptcha-v3": "^1.7.1"

Should have functionality to hide and display captcha badge

I know as per google terms we can not directly hide the captcha badge, But on the other hand we don't want captcha badge all the time.
You should add some prop or something so that we can show badge only when the user is filling the form and after submitting the form we can hide badge.

There are other ways of doing this like
document.getElementsByClassName('grecaptcha-badge')[0].style.opacity = 0
But this is not react way to achieve it

Recaptcha Visibility

Hi,

Just wondering if you have any plans to add a visibility prop to react-google-recaptcha-v3?
You have a really great component here, but in order for me to use it. I'm going to need to make
it invisible

Thanks for your time!

GoogleReCaptcha Context has not yet been implemented

Thanks for creating this library! I have run into a small issue however, and I'm curious whether my use case is supported.

The executeRecaptcha function returned by useGoogleReCaptcha throws a GoogleReCaptcha Context has not yet been implemented error when I try to use GoogleReCaptchaProvider on specific pages, rather than the entire app (in ReactDOM.render). I only want to use it on my app's signup and forgot password pages, because I don't want Google's reCAPTCHA logo in the lower right corner of every page of the app. (It's especially in the way on mobile.)

I'm guessing this is a consequence of using React Context, so you can't use the provider and the hook/consumer in the same component. If so, I think the error message could be improved, such as You can only call useGoogleReCaptcha in a component that is wrapped in GoogleReCaptchaProvider. It would also be helpful if the documentation provided guidance or an example of using the library on specific pages.

import React from 'react';
import { GoogleReCaptchaProvider, useGoogleReCaptcha } from 'react-google-recaptcha-v3';

const { REACT_APP_RECAPTCHA_SITE_KEY } = process.env;

export default function SignupPage(): React.ReactElement {
  const { executeRecaptcha } = useGoogleReCaptcha();
  const onSubmit = React.useCallback(
    (event: React.FormEvent) => {
      event.preventDefault();
      if (!executeRecaptcha) return;
      (async () => {
        try {
          const token = await executeRecaptcha('signup'); // throws context error
          // ...
        } catch (e) {
          // ...
        }
      })();
    },
    [executeRecaptcha]
  );
  return (
    <GoogleReCaptchaProvider reCaptchaKey={REACT_APP_RECAPTCHA_SITE_KEY} scriptProps={{ async: true }}>
      <form onSubmit={onSubmit} noValidate>
        {/* ... */}
      </form>
    </GoogleReCaptchaProvider>
  );
}

This version seems to work:

export default function SignupPage(): React.ReactElement {
  return (
    <GoogleReCaptchaProvider reCaptchaKey={REACT_APP_RECAPTCHA_SITE_KEY} scriptProps={{ async: true }}>
      <SignupForm />
    </GoogleReCaptchaProvider>
  );
}

function SignupForm(): React.ReactElement {
  const { executeRecaptcha } = useGoogleReCaptcha();
  const onSubmit = React.useCallback(
    (event: React.FormEvent) => {
      event.preventDefault();
      if (!executeRecaptcha) return;
      (async () => {
        try {
          const token = await executeRecaptcha('signup');
          // ...
        } catch (e) {
          // ...
        }
      })();
    },
    [executeRecaptcha]
  );
  return (
    <form onSubmit={onSubmit} noValidate>
      {/* ... */}
    </form>
  );
}

Cookies same-site errors

Adding this package I get this errors in console:
image

I've Implemented this package like this:

const SigninPage: FC = () => {
  const [reCaptcha, setReCaptcha] = useState('');
  const { executeRecaptcha } = useGoogleReCaptcha();
  const handleReCaptchaVerify = useCallback(async () => {
    if (!executeRecaptcha) {
      console.log('Execute recaptcha not yet available');
    } else {
      const token = await executeRecaptcha('yourAction');
      setReCaptcha(token);
    }
  }, []);
  useEffect(() => {
    handleReCaptchaVerify();
  }, [handleReCaptchaVerify]);

  const handleSignin = async (values: any) => {
    const data: SigninRequest = {
      [...]
      reCaptcha: reCaptcha || '',
    };
    console.log(data);
    try {
      const response = await axios.post('/auth/signin', data);
      console.log(response);
    } catch (error) {
      console.log(error.response);
    }
  };
  return ([...]);
};

const App: FC = () => {
  return (
    <>
      <GoogleReCaptchaProvider reCaptchaKey="my-key">
        <SigninPage />
      </GoogleReCaptchaProvider>
    </>
  );
};

export default App;

using this package there are 10 cookies that doesn't respect the SameSite attribute.
Can you fix it?

not showing in all pages

I use this package for recaptcha in my react website. i want to show it in only one page .
this package set in contact page but showing in other pages after open contact page.
help me

Captcha only for the specific pages.

hello @t49tran :)

Could you please help me to understand if I need to call captcha on some pages where it needs, how I can do it?
Because I have tried to wrap pages with the captcha provider, but I got the Context issue that I need to wrap the whole app with the CaptchaProvider.

Thank you.

Infinite POST request loop

Environment: NEXT.js

// Recaptcha component
<GoogleReCaptchaProvider reCaptchaKey={process.env.RECAPTCHA_KEY}>
  <GoogleReCaptcha
    onVerify={token => {
      onVerifyCaptcha(token);
    }}
  />
</GoogleReCaptchaProvider>
// pages/access/index.js
const [loaded, setLoaded] = useState(false);
const onVerifyCaptcha =(token) => {
  setLoaded(true); // triggers infinite POST request loop
};
<Recaptcha onVerifyCaptcha={onVerifyCaptcha} />

Possible Solution:

// pages/access/index.js
let validToken = '';

useEffect(() => {
        setLoaded(true);
}, [loaded]);
    
const onVerifyCaptcha = useCallback((token) => {
        validToken = token;
}, [validToken]);

Any feedback/advice regarding this solution or any possible alternative is appreciated. How to use HOC, Class based component with memoizedCallback in order to prevent infinite loop bug?

Site key Error

Sporadically get this error Uncaught (in promise) Error: Invalid site key or not loaded in api.js. I know the key is correct because the error doesn't throw all the time.

TypeError: Cannot read property 'ready' of undefined

Getting error:
TypeError: Cannot read property 'ready' of undefined
My code:

ReactDOM.render(
    <GoogleReCaptchaProvider
        reCaptchaKey="xx"
    >
        <Provider store={configureStore()}>
        <Suspense fallback={<div className="loading" />}>
          <App />
        </Suspense>
      </Provider>
    </GoogleReCaptchaProvider>,
  document.getElementById('root')
);

Call:

  componentDidMount() {
    window.grecaptcha.ready(function() {
      window.grecaptcha.execute('xx', {action: action}).then(function(value) {
        token.currentRecaptchaToken = value;
        console.log(token);
      });
    });
  }

How can I understand component loaded successfully? Thanks advance.

silently hangs if recaptcha key has not been set

Hi, thanks for putting this library together.

I ran into an issue I'll share here for others' benefit.

The problem was when executing the recaptcha fetch, it just hung. I was expecting either an immediate response or maybe throwing some error.

in App.jsx:

import { GoogleReCaptchaProvider } from 'react-google-recaptcha-v3';
<GoogleReCaptchaProvider
  reCaptchaKey={process.env.RECAPTCHA_KEY}
> 
  <Form/>
</GoogleReCaptchaProvider>

then in Form component:

 refetchCaptchaToken = async () => {
    const { googleReCaptchaProps } = this.props;
    return googleReCaptchaProps.executeRecaptcha('submission');
}

but upon calling refetchCaptchaToken in my form submission handler, the await doesn't return, it just hangs.


Solution

It turns out I was passing undefined as the reCaptchaKey to GoogleReCaptchaProvider.
Instead of reCaptchaKey={process.env.RECAPTCHA_KEY} I needed to use reCaptchaKey={process.env.REACT_APP_RECAPTCHA_KEY}.

Still it took some time to debug. Would be great if there was a faster way to notice that error - perhaps throwing an error or console.error logging something?

Cannot invoke an object which is possibly 'undefined'. TS2722

Hi

const { executeRecaptcha } = useGoogleReCaptcha();
executeRecaptcha("").then(data => console.log(data));

is causing an error because executeRecaptcha is optional here:

export interface IGoogleReCaptchaConsumerProps {
    executeRecaptcha?: (action?: string) => Promise<string>;
}

Cannot build with 1.9.1+

I am using react-google-recaptcha-v3 in my project and all worked fine up to 1.9.0 version.
Today tried update to the latest version and got the following error:

Type error: Could not find a declaration file for module 'react-google-recaptcha-v3'. '/MY_PATH/node_modules/react-google-recaptcha-v3/dist/react-google-recaptcha-v3.cjs.js' implicitly has an 'any' type.
  Try `npm i --save-dev @types/react-google-recaptcha-v3` if it exists or add a new declaration (.d.ts) file containing `declare module 'react-google-recaptcha-v3';`

but there is no @types/react-google-recaptcha-v3 package, and it was not needed in version 1.9.0.
The problem is since 1.9.1 version.

I am using TypeScript in my project. Thanks

Use in Japan

Japan blocks google. Is there any way to support China with the other url supported by google for China use.

Timeout for executeRecaptcha on Mobile Chrome

On my Smartphone Chrome
const token = await executeRecaptcha("contact");

fails with a timeout (Stacktrace below)
It works fine on Mozilla and Desktop versions of chrome other mobile versions of chrome.
The issue is probably located upstream. But this might be a good starting point.

Chrome is 83.0.4103.106
Android 10

  | __stack_frame_overlay_proxy_console__ | @ | index.js:2177
-- | -- | -- | --
  | (anonymous) | @ | recaptcha__en.js:92
  | Promise.catch (async) |   |  
  | (anonymous) | @ | recaptcha__en.js:92
  | (anonymous) | @ | recaptcha__en.js:132
  | h.<computed>.next | @ | recaptcha__en.js:156
  | (anonymous) | @ | recaptcha__en.js:326
  | (anonymous) | @ | recaptcha__en.js:326
  | (anonymous) | @ | recaptcha__en.js:131
  | (anonymous) | @ | recaptcha__en.js:91
  | (anonymous) | @ | recaptcha__en.js:206
  | (anonymous) | @ | react-google-recaptcha-v3.esm.js:105
  | Promise.then (async) |   |  
  | (anonymous) | @ | react-google-recaptcha-v3.esm.js:104
  | step | @ | react-google-recaptcha-v3.esm.js:75
  | (anonymous) | @ | react-google-recaptcha-v3.esm.js:56
  | (anonymous) | @ | react-google-recaptcha-v3.esm.js:49
  | __awaiter | @ | react-google-recaptcha-v3.esm.js:45
  | GoogleReCaptchaProvider._this.executeRecaptcha | @ | react-google-recaptcha-v3.esm.js:100
  | _callee$ | @ | SubscribeFooter.tsx:105
  | tryCatch | @ | runtime.js:45
  | invoke | @ | runtime.js:274
  | prototype.<computed> | @ | runtime.js:97
  | asyncGeneratorStep | @ | asyncToGenerator.js:3
  | _next | @ | asyncToGenerator.js:25
  | (anonymous) | @ | asyncToGenerator.js:32
  | (anonymous) | @ | asyncToGenerator.js:21
  | onSubmit | @ | SubscribeFooter.tsx:105
  | (anonymous) | @ | react-hook-form.es.js:1215
  | async function (async) |   |  
  | (anonymous) | @ | react-hook-form.es.js:1199
  | callCallback | @ | react-dom.development.js:189
  | invokeGuardedCallbackDev | @ | react-dom.development.js:238
  | invokeGuardedCallback | @ | react-dom.development.js:293
  | invokeGuardedCallbackAndCatchFirstError | @ | react-dom.development.js:307
  | executeDispatch | @ | react-dom.development.js:390
  | executeDispatchesInOrder | @ | react-dom.development.js:415
  | executeDispatchesAndRelease | @ | react-dom.development.js:3279
  | executeDispatchesAndReleaseTopLevel | @ | react-dom.development.js:3288
  | forEachAccumulated | @ | react-dom.development.js:3260
  | runEventsInBatch | @ | react-dom.development.js:3305
  | runExtractedPluginEventsInBatch | @ | react-dom.development.js:3515
  | handleTopLevel | @ | react-dom.development.js:3559
  | batchedEventUpdates$1 | @ | react-dom.development.js:21872
  | batchedEventUpdates | @ | react-dom.development.js:796
  | dispatchEventForLegacyPluginEventSystem | @ | react-dom.development.js:3569
  | attemptToDispatchEvent | @ | react-dom.development.js:4268
  | dispatchEvent | @ | react-dom.development.js:4190
  | unstable_runWithPriority | @ | scheduler.development.js:653
  | runWithPriority$1 | @ | react-dom.development.js:11040
  | discreteUpdates$1 | @ | react-dom.development.js:21888
  | discreteUpdates | @ | react-dom.development.js:807
  | dispatchDiscreteEvent | @ | react-dom.development.js:4169

Work-around if using react-snap

Hello,

Thanks for making this library.

Unfortunately, I found that it doesn't work with the react-snap library and create-react-app. I'm using the withGoogleReCaptcha HOC, and the executeRecaptcha() function doesn't execute. It also throws no error, so it's not easy to debug.

I wanted to post my workaround in case anybody runs into this issue.

The given code example in the Readme goes like this:

import { GoogleReCaptchaProvider } from 'react-google-recaptcha-v3';
 
ReactDom.render(
  <GoogleReCaptchaProvider
    reCaptchaKey="[Your recaptcha key]"
    language="[optional_language]"
  >
    <YourApp />
  </GoogleReCaptchaProvider>,
  document.getElementById('app')
);

My workaround is this:

const MyReCaptchaProvider = ({ children }: any) => {
  if (navigator.userAgent === 'ReactSnap') return children;

  return (
    <GoogleReCaptchaProvider
      reCaptchaKey="[Your recaptcha key]"
      language="[optional_language]"
    >
      {children}
    </GoogleReCaptchaProvider>
  );
};

ReactDom.render(
  <MyReCaptchaProvider>
    <YourApp />
  </MyReCaptchaProvider>,
  document.getElementById('app')
);

Basically, the work-around tells React-Snap to ignore the GoogleReCaptchaProvider when pre-rendering the page at build time. But when the website loads in the browser and is hydrated, then the GoogleReCaptchaProvider is initialized.

Hope this helps someone.

Upgrading from v1.8.1 to 1.9.X breaks executeRecaptcha

Hello,

We're currently using react 16.14.0 alongisde this package, due to various reasons (and packages) we can't go any further. There's also several react-* packages that are stuck at least a major version behined.

We tried to update the package from 1.8.1 to 1.9.4 (also tried all versions in between) but started getting an undefined function error. (executeRecaptcha is undefined)
We're essentially following the documentation with our usage, and it pretty much matches the withGoogleReCaptcha implementation in the README. I realise the README does state that executeRecaptcha may be removed in future versions. Does 1.9.X remove executeRecaptcha? If no, is there something we're missing?

Thanks in advance!

Problem using the hook

Hello friend, first of all I wanted to thank you for making this library.

The implementation of the hook is not very clear to me.

this line:
const token = executeRecaptcha("login_page");

returns a promise. So if I add the async/await to this function (ReCaptchaComponent ) I have an error rendering the component... Because this function must contains the analysis of the response from server (the score) and must return a component... right?
Something like this: ?

import {
  GoogleReCaptchaProvider,
  useGoogleReCaptcha
} from 'react-google-recaptcha-v3';

// Remember that the hook can only be used within a React functional component
const ReCaptchaComponent = async () => {
  const { executeRecaptcha } = useGoogleReCaptcha();
  const token = await executeRecaptcha("login_page");
  if(token.score (?) > 0.5  ){
     return <MyComponent/>
  else {
      return <MyComponentWithAMessage /> // Component that will show a 'denied' or something like this
   }
}

ReactDom.render(
  <GoogleReCaptchaProvider reCaptchaKey="[Your recaptcha key]">
    <ReCaptchaComponent />
  </GoogleReCaptchaProvider>,
  document.getElementById('app')
);

Is this a correct way? Thanks a lot.

Recaptcha Element isn't visible when hook is used

Hello,

We have noticed that when we use HOC/Hook or context the Recaptcha element doesn't appear at all. However, when we use a component the element is visible. I'm not sure that there is a bug, but according to Recaptcha V3 docs we should show the element or additional labels.

Shouldn't hocs/hooks/context have the same behavior as component?

Thanks for the package!

How hide badge

Hey, thanks for making this package.
I'm using it in the login page but when I enter the dashboard the component is still there, I would like to know how to make it only appear in my login page, or how I can hide it, thank you very much.

My code

App.tsx

return (
    <GoogleReCaptchaProvider reCaptchaKey={process.env.REACT_APP_RECAPTCHA_KEY}>
      <ApolloProvider client={client}>
        <Routes />
      </ApolloProvider>
    </GoogleReCaptchaProvider>
  );

Login.tsx

export const Login: React.FC<RouteComponentProps> = ({ history }) => {
  const { executeRecaptcha } = useGoogleReCaptcha();

async function uLogin() {
    if (!executeRecaptcha) {
      return;
    }
    const result = await executeRecaptcha("login_page");
    setToken(result);
    console.log('token', result);
...
}

return {...}
}

onVerify is not calling in subsequent rendering of the same react component

I have a simple LoginForm component. This is how I have wrapped my component with GoogleReCaptchaProvider component.

render() {
    console.log("calling rendering")
    return (
      <GoogleReCaptchaProvider reCaptchaKey={this.state.recapcharKey}>
        <GoogleReCaptcha onVerify={this.onVerifyCallback} action={"login"}/>
        <div className="form trial-form ml-md-auto">
          ...
        </div>
      </GoogleReCaptchaProvider>
    )
  }

This is my callback function that I submitted for onVerify()

  onVerifyCallback(token) {
    console.log("token received!")
    this.setState({token: token, btnDisable: false, btnTxt: 'Login'})
  }

Problem:

At the initial when the page is rendering, I can see the onVerifyCallback has being triggered. But if I move to a different page(home page) without refreshing my web page, and then come back to login page(which has this shown code) will not trigger the onVerifyCallback method.

Output I see on the browser console:

index.js:1 Timeout (n)
console.<computed> @ index.js:1
(anonymous) @ VM5305 recaptcha__en.js:28
Promise.catch (async)
(anonymous) @ VM5305 recaptcha__en.js:28
(anonymous) @ VM5305 recaptcha__en.js:304
next @ VM5305 recaptcha__en.js:335
(anonymous) @ VM5305 recaptcha__en.js:34
(anonymous) @ VM5305 recaptcha__en.js:34
(anonymous) @ VM5305 recaptcha__en.js:81
(anonymous) @ VM5305 recaptcha__en.js:28
(anonymous) @ VM5305 recaptcha__en.js:344
(anonymous) @ google-recaptcha-provider.tsx:85
Promise.then (async)
(anonymous) @ google-recaptcha-provider.tsx:84
step @ index.js:1
(anonymous) @ index.js:1
(anonymous) @ index.js:1
__awaiter @ index.js:1
GoogleReCaptchaProvider._this.executeRecaptcha @ google-recaptcha-provider.tsx:81
(anonymous) @ google-recaptcha.tsx:22
step @ index.js:1
(anonymous) @ index.js:1
(anonymous) @ index.js:1
__awaiter @ index.js:1
GoogleReCaptcha.componentDidMount @ google-recaptcha.tsx:13
commitLifeCycles @ react-dom.development.js:19814
commitLayoutEffects @ react-dom.development.js:22803
callCallback @ react-dom.development.js:188
invokeGuardedCallbackDev @ react-dom.development.js:237
invokeGuardedCallback @ react-dom.development.js:292
commitRootImpl @ react-dom.development.js:22541
unstable_runWithPriority @ scheduler.development.js:653
runWithPriority$1 @ react-dom.development.js:11039
commitRoot @ react-dom.development.js:22381
finishSyncRender @ react-dom.development.js:21807
performSyncWorkOnRoot @ react-dom.development.js:21793
(anonymous) @ react-dom.development.js:11089
unstable_runWithPriority @ scheduler.development.js:653
runWithPriority$1 @ react-dom.development.js:11039
flushSyncCallbackQueueImpl @ react-dom.development.js:11084
flushSyncCallbackQueue @ react-dom.development.js:11072
discreteUpdates$1 @ react-dom.development.js:21893
discreteUpdates @ react-dom.development.js:806
dispatchDiscreteEvent @ react-dom.development.js:4168
index.js:1 Uncaught (in promise) Timeout (n)

Am I doing/using something wrong?

Token generated at rapid pace in Next.js app

Hi there! I'm using this package in a Next.js app and find that on the page where I have the <GoogleReCaptcha> component placed, the onVerify callback is called very rapidly and new tokens are constantly generated.

I just wanted to know if this is expected.

I'm not doing anything fancy with the component, but here's what the code looks like (roughly):

export default function Contact() {
  const [token, setToken] = useState(null);

  return (
    <>
      // ...
      <GoogleReCaptcha onVerify={ (token) => { setToken(token); console.log(token); } } />
    </>
  );
};

Handle expired token

Hi,

Is it possible to trigger the validation and generated token when the user performs and action? For example when submitting a form?

In my usecase, the entire website is rendered in React. So there can be several minutes between when the user visits the site, and decides to submit the form. The token is expired by then.

LightHouse, unused javascript

Hello,

I've ran an lighthouse report on my site, which uses this lib and one of the main complaints lighthouse has is the size of recaptcha script and the amount of code unused.
I know the javascript is the one the lib gets from google, im wondering if theres any way to work around this?

Screenshot 2020-11-27 at 11 38 48

Thank you

executeRecaptcha is undeifned

Thank you for providing the wrapper to use the recaptcha-v3.

However, I followed the guide here, and I got TypeError: executeRecaptcha is not a function. Could you help ?

import {
  GoogleReCaptchaProvider,
  useGoogleReCaptcha
} from 'react-google-recaptcha-v3';
 
const YourReCaptchaComponent  = () => {
  const { executeRecaptcha } = useGoogleReCaptcha();
  const token = executeRecaptcha("login_page");
 
  return (<div></div>)
}
 
ReactDom.render(
  <GoogleReCaptchaProvider reCaptchaKey="[Your recaptcha key]">
    <YourReCaptchaComponent />
  </GoogleReCaptchaProvider>,
  document.getElementById('app')
);

Refused to execute inline event handler

I started getting the following error in Google Chrome (similar one in Firefox) when loading a component wrapped by <GoogleReCaptchProvider reCaptchaKey="<MY_KEY_HERE>"> ...

Refused to execute inline event handler because it violates the following Content Security Policy directive: "script-src 'report-sample' 'nonce-dbmbCGfTr6E9HqPQS/lyJA' 'unsafe-inline' 'strict-dynamic' https: http: 'unsafe-eval'". Note that 'unsafe-inline' is ignored if either a hash or nonce value is present in the source list.

I tried adding a scriptProps={{nonce:"abc"}} prop but it did nothing (idk if I am using the scriptProps properly but it used to work without it anyway).

In the end the issue is that the { executeRecaptcha } value of useGoogleReCaptcha() is undefined, so I cannot use reCaptcha...

GoogleReCaptchaProvider does not support an initial null reCaptchaKey

If GoogleReCaptchaProvider is initialized with a reCaptchaKey that's initially null, then updated later, the updated key is not taken into account and trying to execute captchas result in an invalid key error.

It would be useful to see it supported, as in our application, the reCaptchaKey is fetched from the backend and fed to the provider using redux / props.

Delaying the script injection until captchaSiteId is initialized would probably suffice.

I could probably create a pull request for it if it can help.

executeRecaptcha hangs when API key missing

First of all, thanks for the awesome package. Makes reCAPTCHA much more usable :)

My bug is that executeRecaptcha can hang. I suspect it's coming from the promise of this.grecaptcha.

I believe this code block might need to check whether recaptcha is ready?

return this.grecaptcha.then(_grecaptcha =>
_grecaptcha.execute(reCaptchaKey, { action })
);

i.e. from the recaptcha docs https://developers.google.com/recaptcha/docs/v3#programmatically_invoke_the_challenge

        grecaptcha.ready(function() {
          grecaptcha.execute('reCAPTCHA_site_key', {action: 'submit'}).then(function(token) {
              // Add your logic to submit to your backend server here.
          });
        });

I'm also looking into a similar issue where the API key is defined, yet somehow it can still hang for me.

`recaptcha__xx.js` script is loaded twice

steps to reproduce

  1. start a new CRA app by npx create-react-app my-app
  2. add GoogleReCaptchaProvider as described in docs, make sure you paste your recaptcha key
    image
  3. start the app and open Network devtools

Actual result

recaptcha__en.js script is loaded twice
image

Expected result

recaptcha__en.js script should is loaded twice

versions used

    "react": "^17.0.2",
    "react-dom": "^17.0.2",
    "react-google-recaptcha-v3": "^1.9.4",
    "react-scripts": "4.0.3",

macOS, Google Chrome 90

Google recaptcha script fails to load on Chromium due to CSP violation

"react-google-recaptcha-v3": "^1.8.0"

Using Chromium:
Version 87.0.4280.66 (Official Build) Built on Ubuntu , running on Ubuntu 18.04 (64-bit)

google-recaptcha-provider.tsx:131 Refused to load the script 'https://www.google.com/recaptcha/api.js?render=<redacted>&hl=en' because it violates the following Content Security Policy directive: "default-src 'self'". Note that 'script-src-elem' was not explicitly set, so 'default-src' is used as a fallback.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.