Zum Inhalt springen

EmailJS in a Next.js

(Step-by-Step Guide)

  • Create an email account on email.js (https://www.emailjs.com)

  • Sign up and log in to your account

  • Connect or link your email with email.js

  • Then the following page will be shown
    Image description
    Click on the Add New Services Button

  • Then click on Gmail when the services open
    Image description

  • Then, click on the Connect Account Button to connect your email. After that, click on the create service button
    Image description

  • After creation, you will get service from that
    Image description

  • Then Click on Email Template
    Image description

  • Then click on the Create New Template Button

Image description

  • Then click on the Create Template button
    Image description

  • Then, set the template that you want and click the save button
    Image description

  • Then, go back to the Email Template and get your templateId
    Image description

  • Then open the account from the left sidebar and get your public key
    Image description

  • After that Install EmailJS in Next.js
    npm install @emailjs/browser

  • After that, set them in the .env file of your project
    ![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/aqj2ii14f0xuft3fffdv.png

  • After that, use the code below or set up in your code

'use client';

import { useState } from 'react';
import { useForm } from 'react-hook-form';
import { FaEnvelope, FaMapMarkerAlt, FaWhatsapp, FaSpinner, FaCheck } from 'react-icons/fa';
import Link from 'next/link';
import TypewriterText from '../TypewriterText';
import emailjs from '@emailjs/browser';

export default function ContactForm() {
  const { register, handleSubmit, formState: { errors }, reset } = useForm({
    defaultValues: {
      firstName: '',
      email: '',
      message: ''
    }
  });

  const [isSubmitting, setIsSubmitting] = useState(false);
  const [isSuccess, setIsSuccess] = useState(false);

  const onSubmit = async (data) => {
    if (isSubmitting) return;

    setIsSubmitting(true);
    setIsSuccess(false);

    const templateParams = {
      from_name: data.firstName.trim(),
      from_email: data.email,
      to_email: process.env.NEXT_PUBLIC_EMAILJS_RECIPIENT_EMAIL || 'naqvi@gmail.com',
      message: data.message,
      reply_to: data.email
    };

    try {
      await emailjs.send(
        process.env.NEXT_PUBLIC_EMAILJS_SERVICE_ID,
        process.env.NEXT_PUBLIC_EMAILJS_TEMPLATE_ID,
        templateParams,
        process.env.NEXT_PUBLIC_EMAILJS_PUBLIC_KEY
      );

      reset();
      setIsSuccess(true);
      setTimeout(() => setIsSuccess(false), 5000);
    } catch (error) {
      console.error('Email sending failed:', error);
      alert('Failed to send message. Please try again or contact me directly at murtjiznaqvi@gmail.com');
    } finally {
      setIsSubmitting(false);
    }
  };

  return (
    <div
      className="p-10 rounded-2xl w-full max-w-6xl mx-auto relative overflow-hidden 
      transform transition-all duration-500 hover:scale-[1.02] border border-gray-200 text-gray-900"
      id="contact"
      aria-labelledby="contact-heading"
      role="region"
    >
      <div className="absolute -top-1/2 -left-1/2 w-[200%] h-[200%] bg-gradient-to-r from-purple-500/10 via-indigo-500/10 to-pink-500/10 opacity-50 blur-3xl rotate-45 -z-10"></div>
      <div className="max-w-6xl mx-auto rounded-xl p-8 md:p-12">
        <div className="absolute inset-0 blur-3xl opacity-40 z-0" />

        <div className="text-center mb-8">
          <TypewriterText text="Get in Touch" id="contact-heading" />
        </div>

        <div className="mb-8 text-center">
          <p className="text-gray-600 mb-4">
            I specialize in crafting elegant, user-focused digital solutions. Let's discuss how I can help bring your ideas to life.
          </p>
          {isSuccess && (
            <div className="bg-green-100 border border-green-400 text-green-700 px-4 py-3 rounded relative" role="alert">
              <span className="block sm:inline">Message sent successfully! I'll get back to you soon.</span>
            </div>
          )}
        </div>

          <form
            onSubmit={handleSubmit(onSubmit)}
            className="flex-1 space-y-6"
            aria-label="Contact Form"
            noValidate
          >
            <div>
              <label htmlFor="firstName" className="sr-only">First Name</label>
              <input
                id="firstName"
                type="text"
                placeholder="First Name"
                className={`w-full px-4 py-3 rounded-lg border ${
                  errors.firstName ? 'border-red-500' : 'border-gray-300 focus:border-indigo-500'
                } bg-white`}
                {...register('firstName', { required: 'First name is required' })}
                aria-invalid={errors.firstName ? 'true' : 'false'}
                aria-describedby={errors.firstName ? 'firstName-error' : undefined}
              />
              {errors.firstName && (
                <p id="firstName-error" className="text-red-400 text-sm mt-1">{errors.firstName.message}</p>
              )}
            </div>

            <div>
              <label htmlFor="email" className="sr-only">Email Address</label>
              <input
                id="email"
                type="email"
                placeholder="Email Address"
                className={`w-full px-4 py-3 rounded-lg border ${
                  errors.email ? 'border-red-500' : 'border-gray-300 focus:border-indigo-500'
                } bg-white`}
                {...register('email', {
                  required: 'Email address is required',
                  pattern: {
                    value: /^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+.[a-zA-Z0-9-.]+$/,
                    message: 'Please enter a valid email address',
                  },
                })}
                aria-invalid={errors.email ? 'true' : 'false'}
                aria-describedby={errors.email ? 'email-error' : undefined}
              />
              {errors.email && (
                <p id="email-error" className="text-red-400 text-sm mt-1">{errors.email.message}</p>
              )}
            </div>

            <div>
              <label htmlFor="message" className="sr-only">Message</label>
              <textarea
                id="message"
                placeholder="Your Message"
                rows={5}
                className={`w-full px-4 py-3 rounded-lg border ${
                  errors.message ? 'border-red-500' : 'border-gray-300 focus:border-indigo-500'
                } bg-white min-h-[150px]`}
                {...register('message', { required: 'Message is required' })}
                aria-invalid={errors.message ? 'true' : 'false'}
                aria-describedby={errors.message ? 'message-error' : undefined}
              />
              {errors.message && (
                <p id="message-error" className="text-red-400 text-sm mt-1">{errors.message.message}</p>
              )}
            </div>

            <button
              type="submit"
              className={`w-full py-3 px-6 rounded-lg font-medium transition-all ${
                isSuccess 
                  ? 'bg-green-600 text-white' 
                  : 'bg-[#0077B5] text-white hover:bg-[#00629c]'
              } flex items-center justify-center gap-2`}
              disabled={isSubmitting}
              aria-busy={isSubmitting}
            >
              {isSubmitting ? (
                <>
                  <FaSpinner className="animate-spin h-5 w-5" />
                  <span>Sending...</span>
                </>
              ) : isSuccess ? (
                <>
                  <FaCheck className="h-5 w-5" />
                  <span>Message Sent!</span>
                </>
              ) : (
                'Submit Message'
              )}
            </button>
          </form>


      </div>
    </div>
  );
}

Link to Github:https://github.com/syedmurtjiz/
Dedicated to crafting high-quality, user-centric web-applications. Explore my work and learn more about my journey at:https://syedmurtjiz-next.netlify.app/

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert