GithubHelp home page GithubHelp logo

snelsi / next-recaptcha-v3 Goto Github PK

View Code? Open in Web Editor NEW
91.0 91.0 8.0 440 KB

⭐ Straightforward solution for using ReCaptcha in your Next.js application

License: MIT License

TypeScript 94.92% JavaScript 5.08%
nextjs react recaptcha recaptcha-v3

next-recaptcha-v3's People

Contributors

kasperadk avatar snelsi avatar takky94 avatar usualdesigner 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

Watchers

 avatar

next-recaptcha-v3's Issues

Add support for the Next 13 `app` directory

Current behavior

Server Error

TypeError: createContext only works in Client Components. Add the "use client" directive at the top of the file to use it. Read more: https://nextjs.org/docs/messages/context-in-server-component

This error happened while generating the page. Any console logs will be displayed in the terminal window.

Reproduction

https://beta.nextjs.org/docs/upgrade-guide#step-2-creating-a-root-layout

// app/layout.tsx

import { ReCaptchaProvider } from "next-recaptcha-v3";

export default function RootLayout({ children }: React.PropsWithChildren) {
  return (
    <html lang="en">
      <body>
        <ReCaptchaProvider>{children}</ReCaptchaProvider>
      </body>
    </html>
  );
}

Solution

See https://beta.nextjs.org/docs/rendering/server-and-client-components#convention

Add "use client"; directive to the top of src/index.tsx or every file that imports useState, useRef or useEffect (src/ReCaptcha.tsx, src/ReCaptchaProvider.tsx and src/useReCaptcha.tsx):

export * from "./recaptcha.types";
export * from "./ReCaptcha";
export * from "./ReCaptchaProvider";
export * from "./useReCaptcha";
export * from "./withReCaptcha";

HOWEVER, Rollup ignores and does not emit "use client"; directives in bundled script. 😅

Workaround

Create a separate file that begins with "use client"; directive and re-export ReCaptchaProvider

app/ReCaptchaProvider.tsx

"use client";

// https://www.typescriptlang.org/docs/handbook/modules.html#re-exports
// eslint-disable-next-line import/prefer-default-export
export { ReCaptchaProvider } from "next-recaptcha-v3";

app/layout.tsx

import { ReCaptchaProvider } from "./ReCaptchaProvider.tsx";

// ...

Documentation "Key"

Documentation should be more specific about which key to use. There is a site key and a secret key.

Next-recaptcha-v3 makes jest test cases fail

Describe the bug
when I try to run the test cases with this package installed the test cases fails

To Reproduce
just install and use the package

Error Message
`
Test suite failed to run

Jest encountered an unexpected token

Jest failed to parse a file. This happens e.g. when your code or its dependencies use non-standard JavaScript syntax, or when Jest is not configured to support such syntax.

Out of the box Jest supports Babel, which will be used to transform your files into valid JS based on your Babel configuration.

By default "node_modules" folder is ignored by transformers.

Here's what you can do:
 • If you are trying to use ECMAScript Modules, see https://jestjs.io/docs/ecmascript-modules for how to enable it.
 • If you are trying to use TypeScript, see https://jestjs.io/docs/getting-started#using-typescript
 • To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
 • If you need a custom transformation specify a "transform" option in your config.
 • If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.

You'll find more details and examples of these config options in the docs:
https://jestjs.io/docs/configuration
For information about custom transformations, see:
https://jestjs.io/docs/code-transformation

Details:

C:\atomica\case-manager-client\node_modules\next-recaptcha-v3\lib\index.js:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,jest){export { ReCaptcha } from './ReCaptcha.js';
                                                                                  ^^^^^^

SyntaxError: Unexpected token 'export'

  11 |   value?: string;
  12 |   onChange?: (v: string) => void;
> 13 | }) {
     |     ^
  14 |   const key = process.env.NEXT_PUBLIC_RECAPTCHA_KEY ?? '';
  15 |   return (
  16 |     <ReCaptchaProvider reCaptchaKey={key}>

  at Runtime.createScriptFromCode (node_modules/jest-runtime/build/index.js:1505:14)
  at Object.<anonymous> (src/components/ReCaptcha/ReCaptcha.tsx:13:26)
  at Object.<anonymous> (src/components/ReCaptcha/index.tsx:11:59)
  at Object.<anonymous> (src/features/Auth/SignUp/components/SignUpForm.tsx:22:20)
  at Object.<anonymous> (src/features/Auth/SignUp/components/signUpForm.test.tsx:23:60)

`

`executeRecaptcha` not referentially stable — mention in docs?

I've just had an issue with using executeRecaptcha, and after debugging it turned out that this function actually changes its value. The first one is essentially just a stub that throws an error, and then, when reCaptcha loads, the value is updated with the working function.

Normally this isn't a problem, but I think that many people would expect that a function returned from a hook is referentially stable, as is usually the case with other hooks. So, when used in, say, a memoized event handler, it needs to be included as a dependency, otherwise the stub version is cached. I know you're supposed to include all functions, but it would be nice to have a reminder.

Besides, you could theoretically use the stub just by calling it fast enough. The hook even returns a loaded prop that could be used to check for it, but it's not mentioned anywhere.

I think this behavior needs to be explained in the docs, together with an explanation of how to use the function correctly.

Other than that, the library works great. Thanks!

reCaptcha script is loaded twice

Describe the bug
A clear and concise description of what the bug is.

When the provider is connected and the page is loaded, the Google Recaptcha script is being loaded twice. That slows down the website performace and is visible in metrics reports. The issue occurs in both Development and Production.

To Reproduce
Steps to reproduce the behavior:

  1. Integrate Recaptcha as per the docs (wrapping the app into the provider).
    'use client'
    
    import { ReactNode } from 'react'
    import { ThemeProvider } from 'next-themes'
    import { ReCaptchaProvider } from 'next-recaptcha-v3'
    
    type Props = {
      children: ReactNode
    }
    
    export default function Providers({ children }: Props) {
      return (
        <ThemeProvider enableSystem attribute="class">
          <ReCaptchaProvider
            id="google-recaptcha-load"
            strategy="afterInteractive"
            reCaptchaKey={process.env.NEXT_PUBLIC_RECAPTCHA_SITE_KEY}
          >
            {children}
          </ReCaptchaProvider>
        </ThemeProvider>
      )
    }
  2. Run "npm dev".
  3. See the Network requests.

Expected behavior
A clear and concise description of what you expected to happen.

The script is loaded once.

Screenshots
If applicable, add screenshots to help explain your problem.

Screenshot 2023-10-06 at 09 55 22 Screenshot 2023-10-06 at 09 52 31 Screenshot 2023-10-06 at 09 59 08

Desktop (please complete the following information):

  • OS: macOS 13.5.2
  • Browser: Firefox 118.0.1, Safari 16.6
  • Version: v1.2.0

Additional context
Add any other context about the problem here.

Next.js 13.2: Error on `executeRecaptcha`

Describe the bug
In the Nextjs 13.2, the token is "not loaded" when I request that the reCaptcha server generate a token. The server responds with the following message:

Uncaught (in promise) Error: Recaptcha has not been loaded
    at eval (webpack-internal:///(:3000/app-client)/./node_modules/next-recaptcha-v3/lib/index.esm.js:140:19)
    at Generator.next (<anonymous>)
    at eval (webpack-internal:///(:3000/app-client)/./node_modules/next-recaptcha-v3/lib/index.esm.js:52:71)
    at new Promise (<anonymous>)
    at __awaiter (webpack-internal:///(:3000/app-client)/./node_modules/next-recaptcha-v3/lib/index.esm.js:48:12)
    at eval (webpack-internal:///(:3000/app-client)/./node_modules/next-recaptcha-v3/lib/index.esm.js:138:93)
    at onSubmit (webpack-internal:///(app-client)/./src/app/(components)/(:3000/forms)/SubscribeFormComponent.js:37:29)
    at eval (webpack-internal:///(:3000/app-client)/./node_modules/react-hook-form/dist/index.esm.mjs:2021:19)

I am using v1.14 of the next-recaptcha-v3

To Reproduce
Steps to reproduce the behavior:

app/layout.js

import '../_css/global.css';
import Header from "../components/header/Header";
import Footer from "../components/footer/Footer";
import qs from "qs";
import axios from "axios";
import {ReCaptchaProvider} from "next-recaptcha-v3";

const querySearch = qs.stringify({populate: ['navigation', 'social_media']}, {encodeValuesOnly: true});

async function getPageData() {
    const response = await axios.get(`...?${querySearch}`);
    return response;
}

export default async function RootLayout({children}) {

    const globalCong = (await getPageData()).data.data;

    return (
        <html lang="en">
        <head/>
        <body>
        <ReCaptchaProvider reCaptchaKey={"......"}>
            <Header globalData={globalCong}/>
            <div className={"page"}>
                {children}
            </div>
            <Footer globalData={globalCong}/>
        </ReCaptchaProvider>
        </body>
        </html>
    )
}

app/contact-us/page.js

"use client"

import React from 'react';
import {useForm} from "react-hook-form";
import axios from "axios";
import {useReCaptcha} from "next-recaptcha-v3";

const SubscribeFormComponent = () => {
    const {executeRecaptcha} = useReCaptcha();

    const { register, handleSubmit, formState: { errors }, reset } = useForm({
        defaultValues: {
            firstname: "",
            lastname: "",
            email: "",
            company: "",
            telephone: "",
            message: ""
        }
    });

    const [isSuccessfullySubmitted, setIsSuccessfullySubmitted] = React.useState(null);

    const onSubmit = async (data) => {
                console.log("data", data);
                const token = await executeRecaptcha('submitForm');
                console.log(token)
                // await axios.post('....', {
                //     token: token,
                //     formData: data})
                //     .then((res) => {
                //         setIsSuccessfullySubmitted(true);
                //     })
                //     .catch((error) => {
                //         setIsSuccessfullySubmitted(false);
                //     }).finally(() => {
                // });
                reset()
    }

Expected behavior
A clear and concise description of what you expected to happen.
The expected behaviour is that on submit, a token should be returned.

Screenshots
If applicable, add screenshots to help explain your problem.

Desktop (please complete the following information):

  • Browser [e.g. chrome, safari]
  • Version [e.g. 22]

Smartphone (please complete the following information):

Additional context
Add any other context about the problem here.

Small issue on example

Describe the bug
React Hook useCallback has missing dependencies: 'executeRecaptcha'

To Reproduce

  const handleSubmit = useCallback(async (e) => {
    e.preventDefault();

    // Generate ReCaptcha token
    const token = await executeRecaptcha("form_submit");

    // Attach generated token to your API requests and validate it on the server
    fetch("/api/form-submit", {
      method: "POST",
      body: {
        data: { name },
        token,
      },
    });
  }, []);

Expected behavior
Correct me if I am wrong, however the [] in your example, (last line of above code snippet) would need to be:
[executeRecaptcha, name]

Smartphone (please complete the following information):

  • Device: [e.g. iPhone6]
  • OS: [e.g. iOS8.1]
  • Browser [e.g. stock browser, safari]
  • Version [e.g. 22]

Additional context
Add any other context about the problem here.

Add support for Checkbox

Hi, I can't find a way to render the Checkbox challenge. When I try using executeRecaptcha method it says I need to add ReCaptcha. But when I switch to ReCaptcha it shows nothing.

Incorrect Token Format Issue with next-recaptcha-v3

Describe the bug
Using next-recaptcha-v3 in a Next.js project leads to the generation of captcha tokens in an incorrect format, causing verification to fail.

To Reproduce
Steps to reproduce the behavior:

  1. Integrate next-recaptcha-v3 with default setup.
  2. Trigger captcha to generate a token for verification.
  3. Observe the token format generated is incorrect.

Expected behavior
Tokens generated should be in the correct format and allow for successful verification with reCAPTCHA v3.

Screenshots
N/A

Desktop (please complete the following information):

  • OS: [Your OS, e.g., Windows 10]
  • Browser [Your browser, e.g., Chrome]
  • Version [Your browser version, e.g., 89]

Smartphone (please complete the following information):
N/A

Additional context
Regenerating the reCAPTCHA keys from the Google Cloud Console temporarily resolves the issue, indicating it might be related to token handling or generation within next-recaptcha-v3.

Passing sitekey through environment variable does not work

Describe the bug
I have my sitekey in .env.local
When I set the sitekey in (in my _app.js file) using the environment variable, accessed through process.env.SITE_KEY, the value is not passed to the script. I get a "client ID is null" error when trying to use reCaptcha. I confirmed there is a value for that environment variable by printing it to the console.

As soon as I hardcode that sitekey into my _app.js file, reCaptcha works fine.

To Reproduce

  1. Set the sitekey in an environment variable
  2. Set the sitekey of in your _app.js or _app.tsx through the env variable using process.env

Sample code:

function MyApp({ Component, pageProps }) {

const siteKey = process.env.RECAPTCHA_SITE_KEY
console.log("My siteKey: ", siteKey)
return (
<ReCaptchaProvider reCaptchaKey={siteKey}>
...

Expected behavior
Recaptcha's sitekey to be set correctly

Screenshots
If applicable, add screenshots to help explain your problem.

Desktop (please complete the following information):

  • MacOS 12.6
  • Chrome

Additional context
Add any other context about the problem here.

Slowed down website by 28% in PageSpeed Insights

Describe the bug
It is bad Idea to include recaptcha js on all pages in nextjs.

Please check the performance before and after:

Before
Screenshot 2024-01-20 at 9 22 24 AM

After:
Screenshot 2024-01-20 at 9 22 33 AM

Google recommends to load it only when you need forms but I've seen if form changes to another form, recapctha fails to load.

Bump to next@14 and update deps

Is your feature request related to a problem? Please describe.
No. Just asking for upte to the most related version.

Describe the solution you'd like
Update the next version to 14.0.0 and update dependecies to the recent versions to prevent deprecation & vulnerabilites.

Note: Actions might contain only alphanumeric characters, slashes, and underscores. Actions must not be user-specific.

Describe the bug
Note: Actions might contain only alphanumeric characters, slashes, and underscores. Actions must not be user-specific.

To Reproduce
Current documentation is incorrect.

Incorrect line:
const token = await executeRecaptcha("form-submit");

Correct Line:
const token = await executeRecaptcha("form/submit");

Source: https://developers.google.com/recaptcha/docs/v3

Actions may only contain alphanumeric characters and slashes, and must not be user-specific.

reCAPTCHA logo appears on every page across app

Describe the bug
If using Next's route with Link as most people will - after reCAPTCHA script has been added to the page, the logo will continue to stay in the bottom right of the site on every page until a full page refresh is made.

To Reproduce
Steps to reproduce the behavior:

  • Add reCaptcha
  • Navigate to different pages and see the logo always follow you

Expected behavior
reCaptcha logo only appears on the page where reCaptcha is used - not across the whole site.

Allow Cloudflare Turnstile as ReCaptcha replacement

Is your feature request related to a problem? Please describe.
Turnstile has ReCaptcha compatible version. It would be great to allow it as well. It would remove dependency on Google.

Describe the solution you'd like
Allow easily use Turnstile via param (same as useEnterprise).

Describe alternatives you've considered
I tried passing src manually. But the API is not 1:1 even though the doc says they have compat layer.

Docs
https://developers.cloudflare.com/turnstile/get-started/migrating-from-recaptcha/

ReCaptcha component now showing.

Describe the bug
I was able to get a token using the useReCaptcha hook. I tried to use the ReCaptcha component according to the docs but nothing appeared in my browser and no errors were shown.

To Reproduce
Follow the steps in the tutorial to use the ReCaptcha component

Expected behavior
I expect some component to appear on the webpage.

Desktop (please complete the following information):

  • OS: MacOS 12.6
  • Chrome

Allow to choose strategy

Describe the solution you'd like
Allow to pass loading strategy into the Provider.

Describe alternatives you've considered
Fork component and do it myself.

Additional context
Since Partytown will soon be in Next.js (currently experimental) it would be great to allow worker strategy (and possibly some other upcoming if they will ever come).

PS: Great job, I was looking for something directly for Next!

recaptcha UI render all over the app

Describe the bug
I used reCaptcha on a single page. but somehow it renders on every page of the app.

To Reproduce
N/A

Expected behavior
It should render on a single page.

Screenshots
If applicable, add screenshots to help explain your problem.

Desktop (please complete the following information):

  • OS: [All OS]
  • Browser [ chrome, safari, edge,brave]

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.