Introduction to Form Handling in Next.js

Forms are an essential part of web applications, allowing users to input and submit data. Next.js provides a flexible environment for handling forms and implementing form validation. In this tutorial, we'll explore how to handle forms and perform form validation in a Next.js application.


Creating a Simple Form

Let's start by creating a basic form in a Next.js component. We'll create a contact form with fields for name, email, and a message:


// components/ContactForm.js
import { useState } from 'react';
function ContactForm() {
const [formData, setFormData] = useState({
name: '',
email: '',
message: '',
});
const handleChange = (e) => {
const { name, value } = e.target;
setFormData({
...formData,
[name]: value,
});
};
const handleSubmit = (e) => {
e.preventDefault();
// Handle form submission, e.g., send data to a server.
};
return (
<form onSubmit={handleSubmit}>
<div>
<label htmlFor="name">Name:</label>
<input type="text" id="name" name="name" value={formData.name} onChange={handleChange} required />
</div>
<div>
<label htmlFor="email">Email:</label>
<input type="email" id="email" name="email" value={formData.email} onChange={handleChange} required />
</div>
<div>
<label htmlFor="message">Message:</label>
<textarea id="message" name="message" value={formData.message} onChange={handleChange} required />
</div>
<button type="submit">Submit</button>
</form>
);
}
export default ContactForm;

Here, we create a controlled form component using React state to manage form data and provide basic form validation by adding the 'required' attribute to form fields.


Form Validation in Next.js

Form validation is crucial to ensure data integrity. Let's add validation for the email field using a simple regular expression:


// components/ContactForm.js
import { useState } from 'react';
function ContactForm() {
const [formData, setFormData] = useState({
name: '',
email: '',
message: '',
});
const [errors, setErrors] = useState({});
const handleChange = (e) => {
const { name, value } = e.target;
setFormData({
...formData,
[name]: value,
});
};
const validateEmail = (email) => {
const emailRegex = /^[a-zA-Z0-9._-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}$/;
return emailRegex.test(email);
};
const handleSubmit = (e) => {
e.preventDefault();
const newErrors = {};
if (!formData.name) {
newErrors.name = 'Name is required';
}
if (!formData.email) {
newErrors.email = 'Email is required';
} else if (!validateEmail(formData.email)) {
newErrors.email = 'Invalid email format';
}
if (!formData.message) {
newErrors.message = 'Message is required';
}
if (Object.keys(newErrors).length === 0) {
// Form is valid, handle submission.
} else {
setErrors(newErrors);
}
};
return (
<form onSubmit={handleSubmit}>
<div>
<label htmlFor="name">Name:</label>
<input type="text" id="name" name="name" value={formData.name} onChange={handleChange} required />
{errors.name && <div>{errors.name}</div>}
</div>
<div>
<label htmlFor="email">Email:</label>
<input type="email" id="email" name="email" value={formData.email} onChange={handleChange} required />
{errors.email && <div>{errors.email}</div>}
</div>
<div>
<label htmlFor="message">Message:</label>
<textarea id="message" name="message" value={formData.message} onChange={handleChange} required />
{errors.message && <div>{errors.message}</div>}
</div>
<button type="submit">Submit</button>
</form>
);
}
export default ContactForm;

In this code, we added a validation function for the email field, checked for required fields, and displayed error messages when validation fails.


Handling Form Submission

After validating the form, you can handle the submission logic. In this example, we'll simulate form submission:


// components/ContactForm.js
// ... (previous code)
const handleSubmit = (e) => {
e.preventDefault();
const newErrors = {};
if (!formData.name) {
newErrors.name = 'Name is required';
}
if (!formData.email) {
newErrors.email = 'Email is required';
} else if (!validateEmail(formData.email)) {
newErrors.email = 'Invalid email format';
}
if (!formData.message) {
newErrors.message = 'Message is required';
}
if (Object.keys(newErrors).length === 0) {
// Form is valid, handle submission.
console.log('Form data submitted:', formData);
} else {
setErrors(newErrors);
}
};
// ... (remaining code)

In this code, we print the form data to the console if the form is valid. In a real application, you would send the data to a server for processing.