Firstly, create a NextJs starter site using the following command.
npx create-next-app@latest my-contact-form --tailwindcss --eslint
Here we are using Next.js 14. So, there are two routers: the app router and the pages router. For our form, it doesn’t matter which router we use, since we are going to implement the form on a single page.
Here, we are using the app router and Tailwind CSS for styling. Let’s remove the default code and create a simple contact form.
export default function Home() {
return (
<div>
<section className="bg-white ">
<div className="py-8 lg:py-16 px-4 mx-auto max-w-screen-md">
<h2 className="mb-4 text-4xl tracking-tight font-extrabold text-center text-gray-900 ">
Contact Us
</h2>
<p className="mb-8 lg:mb-16 font-light text-center text-gray-500 sm:text-xl">
Get In Touch
</p>
<form onSubmit={onSubmit} className="space-y-8">
<div>
<label
htmlFor="name"
className="block mb-2 text-sm font-medium text-gray-900"
>
Your name
</label>
<input
type="text"
id="name"
className="shadow-sm bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-primary-500 focus:border-primary-500 block w-full p-2.5 "
placeholder="jack"
required
/>
</div>
<div>
<label
htmlFor="email"
className="block mb-2 text-sm font-medium text-gray-900"
>
Your email
</label>
<input
type="email"
id="email"
className="shadow-sm bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-primary-500 focus:border-primary-500 block w-full p-2.5 "
placeholder="name@gmail.com"
required
/>
</div>
<div>
<label
htmlFor="subject"
className="block mb-2 text-sm font-medium text-gray-900 "
>
Subject
</label>
<input
type="text"
id="subject"
className="block p-3 w-full text-sm text-gray-900 bg-gray-50 rounded-lg border border-gray-300 shadow-sm focus:ring-primary-500 focus:border-primary-500 "
placeholder="subject"
required
/>
</div>
<div className="sm:col-span-2">
<label
htmlFor="message"
className="block mb-2 text-sm font-medium text-gray-900"
>
Your message
</label>
<textarea
id="message"
rows="6"
className="block p-2.5 w-full text-sm text-gray-900 bg-gray-50 rounded-lg shadow-sm border border-gray-300 focus:ring-primary-500 focus:border-primary-500 "
placeholder="Leave a comment..."
></textarea>
</div>
<button
type="submit"
className="py-3 px-5 text-sm font-medium text-center text-white rounded-lg bg-blue-700 sm:w-fit hover:bg-primary-800 focus:ring-4 focus:outline-none focus:ring-primary-300"
>
Send message
</button>
</form>
</div>
</section>
</div>
);
}
The above will create a simple contact form. Now, let's add the JavaScript needed for the form to store the data in a variable.
export default function Home() {
const onSubmit = async (event) => {
event.preventDefault();
const body = {
name: event.target.name.value,
email: event.target.email.value,
subject: event.target.subject.value,
message: event.target.message.value
};
const json = JSON.stringify(body);
console.log(json)
}
return (
// form code
);
}
now lets create the Access Key from web3Forms
submit your email address and you will get your access key in you mail as below
copy the access key store it in the .env file.
NEXT_PUBLIC_ACCESS_KEY=b746c08a-94d2-4d43-9b9d-5c3002161401
Add this key to the body of the request to send the email. The onSubmit
function will look like this.
const onSubmit = async (event) => {
event.preventDefault();
setResult("Sending....");
const body = {
name: event.target.name.value,
email: event.target.email.value,
subject: event.target.subject.value,
message: event.target.message.value,
access_key: process.env.NEXT_PUBLIC_ACCESS_KEY,
};
const json = JSON.stringify(body);
const response = await fetch("<https://api.web3forms.com/submit>", {
method: "POST",
headers: {
"Content-Type": "application/json",
Accept: "application/json",
},
body: json,
});
const data = await response.json();
if (data.success) {
setResult("Form Submitted Successfully");
event.target.reset();
} else {
console.log("Error", data);
setResult(data.message);
}
};
The complete code of the contact page is here
"use client"; // remove this line if you are using page router
import { useState } from "react";
export default function Home() {
const [result, setResult] = useState("");
const onSubmit = async (event) => {
event.preventDefault();
setResult("Sending....");
const body = {
name: event.target.name.value,
email: event.target.email.value,
subject: event.target.subject.value,
message: event.target.message.value,
access_key: process.env.NEXT_PUBLIC_ACCESS_KEY,
};
const json = JSON.stringify(body);
const response = await fetch("<https://api.web3forms.com/submit>", {
method: "POST",
headers: {
"Content-Type": "application/json",
Accept: "application/json",
},
body: json,
});
const data = await response.json();
if (data.success) {
setResult("Form Submitted Successfully");
event.target.reset();
} else {
console.log("Error", data);
setResult(data.message);
}
};
return (
<div>
<section className="bg-white ">
<div className="py-8 lg:py-16 px-4 mx-auto max-w-screen-md">
<h2 className="mb-4 text-4xl tracking-tight font-extrabold text-center text-gray-900 ">
Contact Us
</h2>
<p className="mb-8 lg:mb-16 font-light text-center text-gray-500 sm:text-xl">
Get In Touch
</p>
<form onSubmit={onSubmit} className="space-y-8">
<div>
<label
htmlFor="name"
className="block mb-2 text-sm font-medium text-gray-900"
>
Your name
</label>
<input
type="text"
id="name"
className="shadow-sm bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-primary-500 focus:border-primary-500 block w-full p-2.5 "
placeholder="jack"
required
/>
</div>
<div>
<label
htmlFor="email"
className="block mb-2 text-sm font-medium text-gray-900"
>
Your email
</label>
<input
type="email"
id="email"
className="shadow-sm bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-primary-500 focus:border-primary-500 block w-full p-2.5 "
placeholder="name@gmail.com"
required
/>
</div>
<div>
<label
htmlFor="subject"
className="block mb-2 text-sm font-medium text-gray-900 "
>
Subject
</label>
<input
type="text"
id="subject"
className="block p-3 w-full text-sm text-gray-900 bg-gray-50 rounded-lg border border-gray-300 shadow-sm focus:ring-primary-500 focus:border-primary-500 "
placeholder="subject"
required
/>
</div>
<div className="sm:col-span-2">
<label
htmlFor="message"
className="block mb-2 text-sm font-medium text-gray-900"
>
Your message
</label>
<textarea
id="message"
rows="6"
className="block p-2.5 w-full text-sm text-gray-900 bg-gray-50 rounded-lg shadow-sm border border-gray-300 focus:ring-primary-500 focus:border-primary-500 "
placeholder="Leave a comment..."
></textarea>
</div>
<button
type="submit"
className="py-3 px-5 text-sm font-medium text-center text-white rounded-lg bg-blue-700 sm:w-fit hover:bg-primary-800 focus:ring-4 focus:outline-none focus:ring-primary-300"
>
Send message
</button>
</form>
<span className="mt-10">{result}</span>
</div>
</section>
</div>
);
}
The Email received will be like below
You can get the source code here