(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
Click on the Add New Services Button -
Then, click on the Connect Account Button to connect your email. After that, click on the create service button
-
Then click on the Create New Template Button
-
Then, set the template that you want and click the save button
-
Then open the account from the left sidebar and get your public key
-
After that Install EmailJS in Next.js
npm install @emailjs/browser
-
After that, set them in the .env file of your project
 {
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/