Using Google reCAPTCHA v3 with Next.js 14

Binay MaharjanBinay Maharjan
3 min read

Google reCAPTCHA v3 is a powerful tool that helps differentiate between human and bot traffic on your website. By integrating it into your Next.js 14 application, you can enhance security and protect against spam and abuse. Here’s a guide to integrating Google reCAPTCHA v3 with a form submission in a Next.js 14 application, using Zod for form validation and Axios for making API requests.

Step 1: Install Required Dependencies

First, ensure you have the necessary dependencies installed:

npm install react-google-recaptcha-v3 zod axios react-hook-form

Step 2: Create the Form Component

In this component, we define the form using react-hook-form for form handling and Zod for validation. We use the useGoogleReCaptcha hook to access the reCAPTCHA token before submission.

import React, { useCallback, useState } from 'react';
import { useForm } from 'react-hook-form';
import { z } from 'zod';
import { zodResolver } from '@hookform/resolvers/zod';
import axiosApi from '@/services/axiosApi';
import { useGoogleReCaptcha } from 'react-google-recaptcha-v3';
import { Input } from '@/components/ui/input'; // This is shadcn Input component
import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage } from '@/components/ui/form'; // UI Form Components

// Zod validation schema
const formSchema = z.object({
  name: z.string().min(1, { message: 'Name is required' }),
  email: z.string().email({ message: 'Invalid email' }),
});

const OurForm = ({ params }) => {
  const { executeRecaptcha } = useGoogleReCaptcha();
  const [isLoading, setIsLoading] = useState(false);

  const form = useForm({
    resolver: zodResolver(formSchema),
    defaultValues: {
      name: '',
      email: '',
    },
  });

  // Submit the form
  const onSubmit = useCallback(
    async (data) => {
      try {
        setIsLoading(true);

        if (!executeRecaptcha) {
          console.error('executeRecaptcha is not ready');
          return;
        }

        const gRecaptchaToken = await executeRecaptcha('form_submit');
        const formData = { ...data, 'g-recaptcha-response': gRecaptchaToken };

        await axiosApi.post(`/form`, formData);

        // Handle success (e.g., navigate to a success page)
      } catch (error) {
        console.error(error);
      } finally {
        setIsLoading(false);
      }
    },
    [executeRecaptcha, params.id]
  );

  return (
    <Form {...form}>
      <form onSubmit={form.handleSubmit(onSubmit)}>
        {/* Form Fields */}
        <FormField
          name="name"
          render={({ field }) => (
            <FormItem>
              <FormLabel>Name</FormLabel>
              <FormControl>
                <Input {...field} placeholder="Enter your name" />
              </FormControl>
              <FormMessage />
            </FormItem>
          )}
        />
        <FormField
          name="email"
          render={({ field }) => (
            <FormItem>
              <FormLabel>Email</FormLabel>
              <FormControl>
                <Input {...field} placeholder="Enter your email" />
              </FormControl>
              <FormMessage />
            </FormItem>
          )}
        />
        <button type="submit" disabled={isLoading}>
          {isLoading ? 'Submitting...' : 'Submit'}
        </button>
      </form>
    </Form>
  );
};

export default OurForm;

Step 3: Wrap Form with GoogleReCaptchaProvider in Parent Component

To enable reCAPTCHA, you need to wrap your form component with GoogleReCaptchaProvider, providing the reCaptchaKey from environment variables.

import React from 'react';
import { GoogleReCaptchaProvider } from 'react-google-recaptcha-v3';
import OurForm from './OurForm';

const OurPage = ({ params }) => {
  const googleReCaptchaKey = process.env.NEXT_PUBLIC_GOOGLE_RECAPTCHA_SITE_KEY;

  return (
    <div className="relative">
      <GoogleReCaptchaProvider reCaptchaKey={googleReCaptchaKey}>
        <OurForm params={params} />
      </GoogleReCaptchaProvider>
    </div>
  );
};

export default OurPage;

Step 4: Setup Environment Variables

In your .env file, add your Google reCAPTCHA site key:

NEXT_PUBLIC_GOOGLE_RECAPTCHA_SITE_KEY=your-site-key // generated from google reCaptcha admin 
NEXT_PUBLIC_GOOGLE_RECAPTCHA_SECRET_KEY=your-secret-key
NEXT_PUBLIC_API_BASE_URL=your-url

Step 5: Axios API Service (axiosApi.js)

Create a reusable Axios instance for making API requests.

import axios from 'axios';

const axiosApi = axios.create({
  baseURL: process.env.NEXT_PUBLIC_API_BASE_URL,
  headers: {
    'Content-Type': 'application/json',
  },
});

export default axiosApi;

This integration helps protect your forms against bots while maintaining a smooth user experience. For example you can visit the link Google-Recaptcha-v3

Conclusion

By integrating Google reCAPTCHA v3 into your Next.js 14 application and utilizing Zod for validation, you can significantly enhance your website's security and protect against spam and abuse. This guide has provided a comprehensive step-by-step approach to implementing reCAPTCHA v3, ensuring a seamless user experience while safeguarding your unwanted requests.
Thank you.

References

https://www.google.com/recaptcha/admin/create

https://www.youtube.com/watch?v=pcxh7cpeboU

https://dev.to/adrianbailador/integrating-recaptcha-v3-in-nextjs-170o

https://www.npmjs.com/package/react-google-recaptcha-v3

https://codesandbox.io/p/devbox/nextjs-google-recaptcha-v3-demo-803er0?file=%2Fpages%2Findex.js

0
Subscribe to my newsletter

Read articles from Binay Maharjan directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Binay Maharjan
Binay Maharjan

πŸ‘‹ Hello World! I'm Binay Maharjan, a passionate Front-End Developer the ever-evolving realm of web development. πŸš€ 🌈 Design Enthusiast: With an eye for aesthetics, I bring designs to life, ensuring a seamless fusion of form and function. My CSS skills extend to animations, transitions, and the art of making websites not just functional, but delightful. πŸ“ Responsive Design Advocate: From desktops to tablets and smartphones, I'm dedicated to creating websites that adapt flawlessly to every screen size. A user-centric approach guides my responsive design philosophy. βš™οΈ Tech Innovator: I thrive on staying up-to-date with the latest trends and emerging technologies in the front-end development landscape. Constantly refining my skills to implement cutting-edge solutions, I am committed to delivering high-quality, forward-thinking code.