(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 ButtonThen, 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/
Top comments (0)