How to easily submit a form in Next.js

Cover Image for How to easily submit a form in Next.js
Ali Bentaleb
Ali Bentaleb

A form is a document that can contain input field in which you can write, or/and a select to choose from a drop down list, and then a submit button where you can click and submit all the typed data

In this tutorial, we are going to show how to submit a form using next.js, and how to highlight input if expected data is not matching the one typed by the user.

Create the input text

We are going first to create our input component which will have:

  • Title
  • Required label to mention next to each input form whether it is required or not
  • Description to help the user understand what to type in the input
  • Default value if there is some default value to set
  • onChange method for handling change in form
  • a boolean validate to determine whether or not to start validation, this is useful to highlight missing fields only after the user clicked on submit

Now, go ahead and create components folder in your next.js root project, under that folder create setupcomponents.js

export function InputWithText({ title, required, description, defaultValue, onChange, validate=false }) {

    // title description input field 

    const className=  validate ? "border-2 border-red-200 rounded w-full py-1 px-2 text-black leading-tight focus:outline-double focus:border-gray-200"
    :"border-2 border-gray-200 rounded w-full py-1 px-2 text-black leading-tight focus:outline-double focus:border-gray-200"
    return (
        <div className="mb-4 mx-2">
            <label className="font-bold text-xs"> {title} </label>{required ? "(required)" : ""}
            <br />
            <span className="text-sm">{description}</span>
                <input className={className} id="inline-full-name" type="text" defaultValue={defaultValue}
                    onChange={onChange} />
                    {validate ? <span className="text-red-500">{title} is mandatory</span> :<></>}

Styling for the component above has been done using tailwindcss, you can follow this guide to install it or you can use any styling that you feel comfortable with

Build the form

Now, let's build the form example with reusing the InputWithText, and creating the submit button

Create pages/form.js

import { InputWithText } from "../components/setupcomponents";
import { useState } from "react";
import isEmail from 'validator/lib/isEmail';
import Head from "next/head";

export default function FormValidation() {

   const [candidat, setCandidat] = useState({ lastName: '', firstName: '', email: '', phone_number: '' })
   const [startValidation, setValidation] = useState(false)

   const onClick = () => {

       if (candidat.lastName === '' || candidat.firstName === '' || === '' || !isEmail( return

       alert('validation OK')

   return (<div className=" display-block flex flex-col justify-center items-center overflow-hidden">
           <title> Next.js submit form</title>
       <div className="flex flex-col mt-6 w-3/4 justify-center">

           <div className="flex w-full p-3 mt-4 border-2 flex-col border-gray-300 rounded-md mb-4 md:w-3/4">
               <span className="font-bold text-2xl mb-4">Apply here</span>
               <InputWithText title={"Last Name"} required={true} onChange={() => { setCandidat({ ...candidat, lastName: }) }} validate={startValidation ? candidat.lastName === '' : false} />
               <InputWithText title={"First Name"} required={true} onChange={() => { setCandidat({ ...candidat, firstName: }) }} validate={startValidation ? candidat.firstName === '' : false} />
               <InputWithText title={"Email address"} required={true} onChange={() => { setCandidat({ ...candidat, email: }) }} validate={startValidation ? === '' || !isEmail( : false} />

               <InputWithText title={"Phone number"} required={true} onChange={() => { setCandidat({ ...candidat, phone_number: }) }} validate={startValidation ? candidat.phone_number === '' : false} />
               <InputWithText title={"Location"} />
               <div className="m-2">
                   <button className="bg-black hover:bg-slate-800 text-white text-sm font-medium p-2 rounded " type="button" onClick={onClick} >

The form has:

  • React state for candidate which will hold lastname, firstname, phone number and email address which are required, and location input field as optional
  • InputWithText component which contain the input, its label and the classname that color the border in red to notify the user that the typed text is not what it is expected
  • next/Head to specify the page name
  • startValidation flag to start validation only after the user hits the submit button
  • onChange method which added the typed parameter by the user to the global state

Validate email address with validator

We have also use an email validator that checks for arobase, a dot and a valid email address before accepting user input, you can install it by using npm i validator, and use the method isEmail to check if the email is valid or not

import isEmail from 'validator/lib/isEmail';
const email=''
const isValidEmail = isEmail(email) // => return true

Test the configuration

Now let's run our server and run http://localhost:3000/form and you will be able to see the form page

nextjs form validation

Now try to hit the submit button and you will notice that mandatory input fields are borderd with red color to indicate that they are mandatory as the image below is showing form validation error in next js

Now try to type in some text in the mandatory field and the red border will disappear instantly

disappearing red border after validating a nextjs form


We have seen how to easily create a form using next.js and how to validate it, as well as to warn the user if anything is missing or that our expectation for a field is not what he/she actually typed.

If you are looking to submit your form data to an api, i recommend to check my article in this link.

Additionaly, you can check how to send a data form to an external api in this link

How to build dynamic sitemap w...How to use React Suspense in N...

More interesting articles