Want to Contribute to us or want to have 15k+ Audience read your Article ? Or Just want to make a strong Backlink?

How to Create a Product Catalog using Cloudinary and Xata.io in Next.js

In keeping with Intelligent Investment, e-commerce gross sales make up 14% – 20% of retail gross sales. Understanding {that a} comparatively giant chunk of our gross sales is made on-line, you will need to discover methods to make it as environment friendly as humanely attainable, thus the creation of product catalogs.

Product catalogs show merchandise at present on sale with the required info a person must make a purchase order. Product catalogs are handy and more and more well-liked.



What we might be constructing

This publish discusses importing product info utilizing the Cloudinary add widget after which storing this product knowledge in a serverless database referred to as Xata.

On the finish of this text, we’ll use these merchandise to construct an e-commerce product catalog.

GitHub URL

https://github.com/Iheanacho-ai/Xata-Ecommerce-Catalog



Conditions

To get probably the most out of this text, we require the next:

  • A fundamental understanding of CSS, JavaScript, and React.js
  • Cloudinary account, we will create a free one here
  • A Xata account. Create a free one here
    ## Organising our Subsequent.js app

Next.js is an open-source React framework that permits us to construct server-side rendered static net functions.

To create our Subsequent.js app, we navigate to our most well-liked listing and run the terminal command under:

    npx create-next-app@newest
    # or
    yarn create next-app
Enter fullscreen mode

Exit fullscreen mode

After creating our app, we alter the listing to the undertaking and begin a improvement server with this terminal code:

    cd <identify of our undertaking>
    npm run dev
Enter fullscreen mode

Exit fullscreen mode

To see our app, we go to http://localhost:3000.



Putting in Tailwind CSS

Tailwind CSS is a “utility-first” CSS framework that enables us to create person interfaces for net functions quickly.

To put in Tailwind CSS in our undertaking, we run these terminal instructions.

    npm set up -D tailwindcss postcss autoprefixer
    npx tailwindcss init -p
Enter fullscreen mode

Exit fullscreen mode

These instructions create two recordsdata within the root listing of our undertaking, tailwind.config.js and postcss.config.js.

In our tailwind.config.js, we add the paths to all our template recordsdata with the code under.

    module.exports = {
      content material: [
        "./pages/**/*.{js,ts,jsx,tsx}",
        "./components/**/*.{js,ts,jsx,tsx}",
      ],
      theme: {
        lengthen: {},
      },
      plugins: [],
    }
Enter fullscreen mode

Exit fullscreen mode

Subsequent, we add the tailwind directives in our kinds/world.css file.

    @tailwind base;
    @tailwind elements;
    @tailwind utilities;
Enter fullscreen mode

Exit fullscreen mode



Putting in the Cloudinary Dependencies

Cloudinary is a cloud-based service that gives an end-to-end picture and video administration answer, together with uploads, storage, manipulations, optimizations, and supply.

We run this terminal command to put in the Cloudinary dependencies in our undertaking.

    npm i @cloudinary/url-gen @cloudinary/react
Enter fullscreen mode

Exit fullscreen mode



Organising a Xata Workspace

Xata is a serverless data platform that gives builders a serverless relational database, search engine, and analytics engine, all behind the constant API.

Xata permits builders to construct functions simpler and quicker.

To start out utilizing Xata, we have to create a workspace. Xata workspaces signify our organizations and assist to safe our knowledge.

Subsequent, we click on on ‘Add a database’ to create a database.

Xata Database

After creating our database, we click on on ‘Begin from Scratch’ to create tables.

Xata Database

We add tables by clicking the ‘+’ icon on the desk header. These tables can signify knowledge attributes, and we’ll create three extra tables that are:

  • productName, which holds strings
  • productPrice, which has integers ****
  • productURL, which accommodates hyperlinks

Xata Database



Putting in Xata

After we created our Xata database, we have to set up the Xata CLI globally with this terminal command:

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

Exit fullscreen mode

Subsequent, we authenticate ourselves by logging in with this terminal command:

    xata auth login
Enter fullscreen mode

Exit fullscreen mode

When executing this command, we’ve two choices: to create a brand new API key or use an present one. We’ll create a brand new API key as a result of this can be a new undertaking. To know extra about Xata API keys, try the Xata documentation.

Subsequent, we initialize our undertaking by operating this terminal command:

    xata init
Enter fullscreen mode

Exit fullscreen mode

Working this command will immediate a questionnaire. We must always reply these questions as observe:

Xata Initialization Questionnaire

After answering the questions, Xata provides our API key to our .env file and units up our undertaking.

We then restart our improvement server to learn the contents in our .env file.



Creating our Product Catalog

We create our product catalog web page in our index.js file. This web page might be divided into two sections, one to gather product knowledge and the opposite to show the product knowledge.

On this part, we’re going to work on the shape for the gathering of product knowledge. To create the Tailwind CSS-styled kind, we paste this code into our index.js file.

[https://gist.github.com/Iheanacho-ai/998c7ba832c21a36ff7226e03ee4a4a0]

Subsequent, we add these kinds to middle and re-size our kind in our world.css file.

    .product-container{
      margin-left: 37%;
      width: 30%;
    }
Enter fullscreen mode

Exit fullscreen mode

Right here is how our product catalog kind seems:

Product Catalog Application



Embedding the Cloudinary Add Widget

To add photos to our Xata database, we’ll use the Cloudinary add widget. The Cloudinary add widget is an interactive person interface that enables customers to add media from numerous sources.

We have to embody the Cloudinary widget JavaScript file within the Head part of our index.js file to make use of the widget.

    <div className= 'product-catalog'> 
        <Head>
          <script src="https://upload-widget.cloudinary.com/world/all.js" kind="textual content/javascript"/>
        </Head>
     ...
Enter fullscreen mode

Exit fullscreen mode

Creating an add preset
With Cloudinary’s add presets, we will outline actions or a set of actions that we need to happen after we add a bit of media.

It is very important outline add presets with the Cloudinary widget.

To create an add preset, we go to our Cloudinary Console and click on on the Settings tab.

Cloudinary Console

Subsequent, we click on on the Add tab and scroll all the way down to the Add presets part of the web page.

Cloudinary Console Upload tab
Cloudinary Console Upload Page

We then click on on Add add preset. We are able to use the add preset identify given to us by Cloudinary, or we will rename the add preset.

Then we alter the Signing Mode to ‘Unsigned’ and click on the Save button to avoid wasting our add preset.

Cloudinary Upload Preset Page

We then copy the add preset identify as we’d like it when creating our add widget.

Subsequent, we create an openupWidget() operate to embed and open up our widget. In our index.js file, we write this piece of code:

    const openupWidget = () => {
      window.cloudinary.openUploadWidget(
        { cloud_name: ***, //we add our cloud identify hwe
          upload_preset: 'xoskczw2'
        },
        (error, consequence) => {
          if (!error && consequence && consequence.occasion === "success") {
            console.log(consequence.data.url)       
          }else{
            console.log(error)
          }
        }
      ).open();
    } 

Enter fullscreen mode

Exit fullscreen mode

Within the code block above, we do the next:

  • Use the openUploadWidget() technique that receives two parameters, the cloud_name and our add preset. To get our cloud_name, we go to our Cloudinary Dashboard

  • Logs the picture URL or the error encountered to the console relying on if the add was profitable or not

Subsequent, we go the openupWidget() operate to an onClick occasion listener on our “Add recordsdata” button. The onClick occasion listener calls our openupWidget() operate every time we click on our button

    <button className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded" kind="button" onClick= {openupWidget}>
        Add recordsdata
    </button>
Enter fullscreen mode

Exit fullscreen mode



Including Interplay with our Xata Database

To effectively retailer, retrieve and delete knowledge from our Xata database, we have to create three variables, productName, productPrice, productURL. To create the variables we’d like, we begin by importing the useState hook in our index.js file.

    import { useState } from 'react';
Enter fullscreen mode

Exit fullscreen mode

Subsequent, we create the variables with this piece of code:

    const [productName, setProductName] = useState();
    const [productPrice, setProductPrice] = useState();
    const [productURL, setProductURL] = useState()
Enter fullscreen mode

Exit fullscreen mode

The variables maintain the next info:

  • The productName variable holds the identify of our product
  • The productPrice variable holds the value of a product
  • The productURL variable holds the picture URL of the product

We replace our productURL variable via the openUpWidget() operate.

     const openupWidget = () => {
        window.cloudinary.openUploadWidget(
          { cloud_name: 'amarachi-2812',
            upload_preset: 'xoskczw2'
          },
          (error, consequence) => {
            if (!error && consequence && consequence.occasion === "success") {
              //we save the picture URL within the productURL variable
              setproductImage(consequence.data.url)
            }
          }
        ).open();
      } 
Enter fullscreen mode

Exit fullscreen mode

Subsequent, we put the productName and productPrice variables of their respective enter fields to retailer the enter values.

    {/* productName variable goes right here */}

    <div className="mt-1">
        <textarea
            id="about"
            identify="about"
            rows={1}
            worth= {productName}
            onChange = {(e)=> setProductName(e.goal.worth)}
            className="shadow-sm focus:ring-indigo-500 focus:border-indigo-500 mt-1 block w-full sm:text-sm border border-gray-300 rounded-md"
          />
    </div>
Enter fullscreen mode

Exit fullscreen mode

    {/* productPrice variable goes right here */}

    <enter
      kind="textual content"
      identify="value"
      id="value"
      worth= {productPrice}
      onChange = {(e)=> setProductPrice(e.goal.worth)}
      className="focus:ring-indigo-500 focus:border-indigo-500 block w-full pl-7 pr-12 sm:text-sm border-gray-300 rounded-md"
      placeholder="0.00"
    />

Enter fullscreen mode

Exit fullscreen mode

Including knowledge to our database
In our api/pages folder, we add a add-product.js file to permit us safely work together with our database with out exposing our Xata API key.

Subsequent, we add this code in our /api/add-product.js file.

    //pages/api/add-product.js
    import { getXataClient } from '../../src/xata';

    const xata = getXataClient();
    const handler = async (req, res) => {
      const {productName, productPrice, productURL} = req.physique;
      const consequence = await xata.db.product.create({productName, productPrice, productURL});
      res.ship({consequence});
    };
    export default handler;
Enter fullscreen mode

Exit fullscreen mode

Within the code block above, we do the next:

  • Import the getXataClient from the xata file that was routinely created for us throughout initialization. We then create a brand new occasion with the getXataClient object
  • We pull out the productName, productPrice, productURL variables from the physique of our request so as to add to the database
  • Move the variables within the Xata create technique to create knowledge on our database. When passing the variables in as a parameter, you will need to notice this stuff:
    • The create() is on the product object as a result of our database’s identify is ‘product’
    • The variables are the identical because the tables on our database
  • Lastly, we ship the ensuing knowledge to the shopper facet after saving the info in our database

To question the api/add-product endpoint, we create a submitProduct() in our index.js file.

    const submitProduct = () => {
      fetch('/api/add-product', {
        technique: 'POST',  
        headers: {
          'Content material-Kind': 'software/json'
        },
        physique: JSON.stringify({
          productName,
          productPrice,
          productURL
        })
      }).then(() => {
          window.location.reload()
        }).catch((error)=> {
          console.log(error)
        });
    }
Enter fullscreen mode

Exit fullscreen mode

Within the code block above, we question the /api/add-product endpoint that may safely hook up with Xata. We then go the productName, productPrice, and productURL variables within the request’s physique in order that the /api/add-product API can entry them.

Subsequent, we go the submitProduct operate to the onClick occasion listener on our ‘Save’ button.

    <button
        kind="submit"
        onClick={submitProduct}
        className="cursor inline-flex justify-center py-2 px-4 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500"
        >
          Save
    </button>
Enter fullscreen mode

Exit fullscreen mode

Deleting knowledge from our database
In our pages/api folder, we create a delete-product.js file. The delete-product.js file will comprise this code.

    //api/delete-product

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

    const xata = getXataClient();
    const handler = async (req, res) => {
      const { id } = req.physique;
      await xata.db.product.delete(id);
      res.finish();
    };
    export default handler;
Enter fullscreen mode

Exit fullscreen mode

Within the code block above, we delete a product from our database utilizing a id that we get from the request physique.

In our index.js file, we create a deleteProduct() operate to question our /api/delete-product endpoint.

    const deleteProduct = (id) => {
      fetch("/api/delete-product", {
        technique: "POST",
        headers: {
          "Content material-Kind": "software/json",
        },
        physique: JSON.stringify({ id }),  
      }).then(() => {
        window.location.reload();
      }).catch((error)=> {
          console.log(error)
      });
    }
Enter fullscreen mode

Exit fullscreen mode

Within the code block above, go within the id of the product we need to delete. The /api/delete-product handler wants the id to search out and efficiently delete a product. After deleting the product, we reload the window to replicate the adjustments in our software.

Accumulating Information from our database
After writing the logic for creating and deleting knowledge, we need to accumulate it in our database and render it in our software.

In our ìndex.js file, we write this code:

    export const getServerSideProps = async () => {
      const xata = getXataClient();
      const merchandise = await xata.db.product.getAll()
      return { props: { merchandise } }
    }
Enter fullscreen mode

Exit fullscreen mode

Querying our knowledge in getServerSideProps collects our knowledge earlier than we render the web page and, extra importantly, runs on the backend, as it’s safer.

We accumulate all of the merchandise on our database and go them as props to the Dwelling operate that homes our house web page.

    const Dwelling = ({merchandise}) => {
        return(
          ...
        ) 
    }

    export const getServerSideProps = async () => {
      const xata = getXataClient();
      const merchandise = await xata.db.product.getAll()
      return { props: { merchandise } }
    }
Enter fullscreen mode

Exit fullscreen mode

After this part, right here is how our index.js file seems:

https://gist.github.com/Iheanacho-ai/2b838d9d4d30b548c4a82edfb0d733e8



Creating our Product Show Part

After a product has been created and saved on our database, we need to render it on our house web page.

In our index.js file, we write this piece of code.

    <div className="bg-white">
      <div className="max-w-2xl mx-auto py-16 px-4 sm:py-24 sm:px-6 lg:max-w-7xl lg:px-8">
          <h2 className="sr-only">Merchandise</h2>
          <div className="grid grid-cols-1 gap-y-10 sm:grid-cols-2 gap-x-6 lg:grid-cols-3 xl:grid-cols-4 xl:gap-x-8">
              {
                 merchandise.map(({productName, productURL, productPrice, id}) => (
                    <a href="#" className="group" id={id}>
                        <div className="w-full aspect-w-1 aspect-h-1 bg-gray-200 rounded-lg overflow-hidden xl:aspect-w-7 xl:aspect-h-8">
                          <img src={productURL} alt="Tall slender porcelain bottle with pure clay textured physique and cork stopper." className="w-full h-full object-center object-cover group-hover:opacity-75" />
                        </div>
                      <h3 className="mt-4 text-sm text-gray-700">{productName}</h3>
                      <p className="mt-1 text-lg font-medium text-gray-900">${productPrice}</p>

                  {/* delete button goes right here */}
                      <button
                        kind="button"
                          className="cursor inline-flex justify-center py-2 px-4 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500"
                          onClick={()=> deleteProduct(id)}
                        >
                      Delete
                    </button>
                  </a>
                ))
              }
          </div>   
      </div>
    </div>
Enter fullscreen mode

Exit fullscreen mode

Within the code block above, we do the next:

  • Loop via the merchandise we get as props to render every product with its identify, value, and picture URL.
  • Add the deleteProduct operate to an onClick occasion listener on our “Delete” button.

With this, we’ve created our product catalog. Right here is how our index.js file seems:

https://gist.github.com/Iheanacho-ai/c21a816dc8170fff83c025953fb88a64

That is how our software seems:

Product Catalog Application

We open up our Xata workspace to see our created merchandise.

Xata Database



Conclusion

This text discusses making a product catalog with Cloudinary and Xata’s serverless database. Using the Cloudinary add widget, we collected knowledge on merchandise and saved them on our database in Xata.



Sources

These sources will be helpful:

Add a Comment

Your email address will not be published. Required fields are marked *

Want to Contribute to us or want to have 15k+ Audience read your Article ? Or Just want to make a strong Backlink?