Blog>
Snippets

Integrating TailwindCSS Forms Plugin with Next.js Form Handling

Showcase how to use the TailwindCSS Forms plugin to style forms in Next.js and handle form submission with server-side validation.
import 'tailwindcss/tailwind.css';
import { useForm } from 'react-hook-form';

export default function ContactForm() {
  const { register, handleSubmit, errors } = useForm();

  const onSubmit = async data => {
    try {
      const response = await fetch('/api/contact', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
        },
        body: JSON.stringify(data),
      });
      if (response.ok) {
        // Handle success
      } else {
        // Handle error
      }
    } catch (error) {
      // Handle exception
    }
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)} className="space-y-6">
      <div>
        <label htmlFor="name" className="block text-sm font-medium text-gray-700">
          Name
        </label>
        <input
          type="text"
          name="name"
          id="name"
          ref={register({ required: true })}
          className="mt-1 block w-full px-3 py-2 bg-white border border-gray-300 rounded-md shadow-sm placeholder-gray-400 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"
        />
        {errors.name && <span className="text-red-500">Name is required</span>}
      </div>
      <!-- More form fields here -->
      <div>
        <button type="submit" className="w-full flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
          Submit
        </button>
      </div>
    </form>
  );
}
This code sets up a Next.js form component using react-hook-form for form handling and TailwindCSS for styling. It defines a form with validation on the client's name field and sends the form data to a server-side API endpoint on submission. Upon a successful response, it can handle success or errors appropriately, including HTTP errors and exceptions.
import { NextApiRequest, NextApiResponse } from 'next';

export default async (req: NextApiRequest, res: NextApiResponse) => {
  if (req.method === 'POST') {
    const { name, email, message } = req.body;
    // Perform server-side validation
    if (!name || !email || !message) {
      return res.status(400).json({ error: 'Missing fields' });
    }
    try {
      // Handle form submission, e.g., save to database, send email, etc.
      // ...
      return res.status(200).json({ success: true });
    } catch (error) {
      return res.status(500).json({ error: 'Internal Server Error' });
    }
  } else {
    // Handle other HTTP methods or return method not allowed
    res.setHeader('Allow', ['POST']);
    return res.status(405).json({ error: 'Method Not Allowed' });
  }
};
This is the Next.js API route handler for the contact form. It only accepts POST requests and performs server-side validation to check if all required fields are present. On successful validation, the form submission is handled, for example, inserting data into a database or sending an email. Errors in the operation will send an appropriate HTTP status code and message back to the client. If the request method is not POST, the server responds with 'Method Not Allowed'.