How to Build Forms in Next Using Xata and Cloudinary

teri - Nov 24 '22 - - Dev Community

Forms are essential in collecting user data on web applications. They allow users to input and submit data directly from a login screen or checkout page.

Having a customer feedback form attached to a web page is vital for every modern website as this data can be stored in a database once submitted.

In this tutorial, you’ll learn how to use the React framework, Next.js, in combination with Xata, a serverless database with built-in powerful search and analytics and Cloudinary, a cloud-based media library for images and videos to build a customer feedback form.

Prerequisites

The following are required to complete this tutorial:

  • For installation of development dependencies and packages, you will need to have Node installed on your local machine
  • Tailwind CSS will handle the styling of the application. For setup, follow this installation framework guide
  • Basic knowledge of JavaScript
  • Create an account on Xata and Cloudinary. Sign-up is free

Demo

Check out the deployed project of the customer feedback form.

Repository

In this GitHub repo, you can find the complete source code.

Creating a Database

After creating your Xata account, go to your workspace dashboard and create a new database. For this project, the database name is called collect_user_data. You are at liberty to name it whatever.

xata db

Next, create a table called customers that will hold data collection in a schema. The schema should look something like this:

xata schema

Note: The auto-generated IDs are unique for each new record.

Installation and Setup

To begin, scaffold a new Next app with all the files and folders with this command in your terminal:

npx create-next-app <app-name>
Enter fullscreen mode Exit fullscreen mode

After installation, navigate to the created directory and run the command below to start the development server on port 3000.

cd <app-nam>

npm run dev
Enter fullscreen mode Exit fullscreen mode

Open http://localhost:3000 in your browser to confirm it is running.

Setup Xata Instance

To initialize the customer feedback form app, install the Xata CLI globally. Run the following command:

npm install @xata.io/cli -g
Enter fullscreen mode Exit fullscreen mode

Next, let’s run the following command:

xata auth login
Enter fullscreen mode Exit fullscreen mode

If this is your first time running this command, it will open a new window in the browser to authenticate your account. Afterwards, it will prompt you to Create a new API key or use an existing one; go with the former.

xata authentication

Make sure you copy and paste the API key provided by Xata in the .env file as a variable.

Now in the project directory, run the command:

xata init
Enter fullscreen mode Exit fullscreen mode

This command will initialize your project locally with several prompts to set up Xata in your app. The options should look something like this:

initialize the project

Upload the Image to Cloudinary

Go to your Cloudinary dashboard and upload an image in the media library.

cloudinary

Copy the link to the image to be used later in the application.

cloudinary media library

Creating a Basic Form

In this section, you’ll create an empty form with HTML elements and a submit button using JSX. Copy and paste the following code with the Tailwind CSS classes to handle the styling of the form.

Open the pages/index.js file and clear out the existing code with this:

https://gist.github.com/Terieyenike/57741807dca96a1e56b4da7a9b95048c

Your home page should look something like this:

form page

Collecting Form Data

Testing the app in the browser and clicking the submit button, the page reloads. Since this is a single-page application, you’ll pass in an event handler to the <form> element, not the <button>, to handle the event.

Update the index.js file with the useState hook to create states and later update the state to get the value of the input with the handleChange function and submit the form with the handleSubmit function.

Copy and paste the updated code:

https://gist.github.com/Terieyenike/26a66ddeeef3691161ada3dce58d000c

The .preventDefault() is to stop the page from submitting the form.

Creating Data

In the api folder within pages, create a new file called add-detail.js. Copy and paste the following code:

// pages/api/add-detail.js

import { getXataClient } from '../../src/xata';

const handler = async (req, res) => {
 const xata = await getXataClient();

const { first_name, last_name, email, company, message, hear_about_us } = req.body;
 await xata.db.customers.create({
  first_name,
  last_name,
  email,
  company,
  message,
  hear_about_us,
});
  res.end();
};

export default handler;
Enter fullscreen mode Exit fullscreen mode

The import getXataClient is present in the app when the project is initialized with the xata command. Next.js is to create asynchronous function called handler with the req and res parameters. The req.body will handle the values from the data submitted in the request body from the form with the individual declared data type from the Xata database.

Next, pass in the data as an object in the create() function.

Submitting the Form

Back in the index.js, let’s create another function that will handle the form data submission into Xata to store and persist the data in the database, which on success, shows a message that the data was saved successfully.

But first, let’s create a file, success.js and copy the following code:

// pages/success.js

import Link from 'next/link';

    const Success = () => {
      return (
        <section className='bg-gray-900'>
          <div className=' mx-auto max-w-6xl w-4/5'>
            <div className='flex items-center justify-center min-h-screen flex-col'>
              <p className='text-white text-2xl lg:text-4xl capitalize text-center mb-10'>
                message sent successfully. We would get back to you
              </p>
              <Link
                href='/'
                className='text-white bg-green-800 font-bold py-1 px-3'>
                Return home
              </Link>
            </div>
          </div>
        </section>
      );
    };

export default Success;
Enter fullscreen mode Exit fullscreen mode

This page lets you click on a link that returns you to the home page with the Tailwind CSS classes.

The success page should look like this:

success page

Returning to index.js, update the file with the submit function.

// pages/index.js

{/* other imports */}
import { useRouter } from 'next/router'

export default function Home() {
      const router = useRouter();

      {/* form state */} 

      const submit = () => {
        fetch('/api/add-detail', {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
          },
          body: JSON.stringify({
            first_name,
            last_name,
            email,
            company,
            message,
            hear_about_us,
          }),
        }).then(() => router.push('/success'));
      };

      const handleSubmitForm = (e) => {
        e.preventDefault();
        submit();
      };

      return (
        <div>
          {/* head element */}
          <main className='min-h-screen flex flex-col'>
            <div className='flex flex-col lg:flex lg:flex-row'>
              <div className='mx-auto max-w-6xl w-4/5 lg:p-8'>
                <div className='mt-8 lg:mt-0'>
                  <h1 className='font-bold text-2xl mb-2'>
                    Let&apos;s work together
                  </h1>
                  <p>
                    We&apos;d love to hear from you! Send us a message and we will
                    get back to you.
                  </p>
                </div>
                <form onSubmit={handleSubmitForm}>
                  {/* other JSX */}
                </form>
              </div>
              {/* image container */}
            </div>
          </main>
        </div>
      );
}
Enter fullscreen mode Exit fullscreen mode

The following occurs in the snippet code above:

  • Import the useRouter hook to have access to the router object inside any function component in your app
  • Within the submit function, the use of the fetch method to call the add-detail file and send network requests to the server using the POST method and headers. In addition, the form data submitted is in the form of an object in JSON format
  • Finally, using router.push navigate to the success page on successful form submission

The final code for the index.js file:

https://gist.github.com/Terieyenike/a1b73d31e428e49e6b068d2b9b789db8

Deployment

The customer feedback form app is deployed on Vercel. There are many other options that one can use to deploy a client-side application. If you want to use Vercel, check out its documentation.

Project Demo

Conclusion

This article taught you how to create a customer feedback form with the Next.js framework and store your collected data with Xata.

Try using Xata and Cloudinary.

Learn More

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .