<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Akunne Pascal</title>
    <description>The latest articles on DEV Community by Akunne Pascal (@kodecheff).</description>
    <link>https://dev.to/kodecheff</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F435618%2Fd2c5d47e-8040-4fca-8f63-f2e47001bdf3.jpg</url>
      <title>DEV Community: Akunne Pascal</title>
      <link>https://dev.to/kodecheff</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/kodecheff"/>
    <language>en</language>
    <item>
      <title>Building an E-commerce Storefront using Nextjs, Cloudinary, and Xata</title>
      <dc:creator>Akunne Pascal</dc:creator>
      <pubDate>Wed, 23 Nov 2022 07:11:07 +0000</pubDate>
      <link>https://dev.to/hackmamba/building-an-e-commerce-storefront-using-nextjs-cloudinary-and-xata-50pk</link>
      <guid>https://dev.to/hackmamba/building-an-e-commerce-storefront-using-nextjs-cloudinary-and-xata-50pk</guid>
      <description>&lt;p&gt;In a world where over 4.5 billion people access the internet daily, it has become an integral part of our lives because it affects our social interactions in so many ways. One is the increase in the number of people making purchases online. To create online stores, business owners have turned to online platforms like Shopify. These factors have led to an increase in the importance of online sales in our economy. E-retail sales have surpassed 5.7 trillion dollars globally, and this number is only likely to rise in the upcoming years.&lt;/p&gt;

&lt;p&gt;In this article, you will learn how to integrate Xata and Cloudinary to Nextjs to build an E-commerce storefront, the presentation layer of an online store that communicates with online customers. Nextjs is a React framework used to create the user interface. Cloudinary is a robust media API used to manage media files, and Xata is a serverless database that stores users' data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisite
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Npm&lt;/li&gt;
&lt;li&gt;Node&lt;/li&gt;
&lt;li&gt;Git&lt;/li&gt;
&lt;li&gt;Basic knowledge of Reactjs and Nextjs&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Getting started
&lt;/h2&gt;

&lt;p&gt;The entire source code for this application is publicly accessible on GitHub. You can clone it locally to your computer. This article will concentrate on how we will be utilizing Xata and Cloudinary in the project.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;&lt;a href="https://cloudinary.com/?utm_source=hackmamba&amp;amp;utm_campaign=hackmamba-hackathon&amp;amp;utm_medium=hackmamba-blog"&gt;Cloudinary&lt;/a&gt; is a powerful media API for websites and mobile apps alike. Developers and marketers can effectively create, manage, and deploy their digital experiences using any browser, device, or bandwidth, thanks to Cloudinary. The architecture of Cloudinary was designed from the ground up to withstand enormous loads and manage essentially infinite amounts of assets and consumption.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;After you clone it, you must add a Xata API key, Cloudinary cloud name, and the &lt;strong&gt;upload preset&lt;/strong&gt; in an &lt;code&gt;.env&lt;/code&gt; file at its root if you want to execute it locally.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Upload presets can be defined as a collection of activities that would occur upon uploading a resource. These activities could include applying an add-on capability, performing a transformation, or altering a resource's access control, among many other possibilities.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To clone the application, run the following command on the terminal.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git clone https://github.com/HarcourtHamsa/Frontier.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Create a &lt;code&gt;.env&lt;/code&gt; file in the root directory and paste your Xata api key&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;XATA_API_KEY=&amp;lt;your Api key&amp;gt;
CLOUD_NAME=&amp;lt;your cloudinary cloud name&amp;gt;
UPLOAD_PRESET=&amp;lt;your cloudinary upload preset&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Start the project&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm run dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  Adding Xata CLI
&lt;/h3&gt;

&lt;p&gt;Xata is a serverless database with robust search and analytics. It is comparable to a serverless relational database, a search engine, and an analytics engine, all hidden behind a uniform API.&lt;/p&gt;

&lt;p&gt;It is advisable to use the SDK when adding Xata to the project; We can use the SDK in many JavaScript runtimes, including Node.js, Deno, Electron, etc.&lt;/p&gt;

&lt;p&gt;To install Xata, run the command:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm i -g @xata.io/cli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Next, we have to authenticate Xata with the command&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;xata auth login
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;With the stated command, you can either paste in an existing API key or create a new one by opening a browser.&lt;/p&gt;

&lt;p&gt;Also, you will need to configure the application with the command below:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;xata init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;The command above will start a brief survey that will assist us in setting up our project. Answer the questions, and use code generation. &lt;/p&gt;

&lt;p&gt;Now that Xata is set up in the project, you can query data with the utmost security and efficiency.&lt;/p&gt;
&lt;h3&gt;
  
  
  Creating Xata API
&lt;/h3&gt;

&lt;p&gt;To add an API key, you'll go to your account settings, where you can add an API key. There you will be required to submit a name to generate a key. Because your key will only be shown to you once before becoming inaccessible for security reasons, ensure you copy it to a secure area. You can invalidate and create a new key if you misplace this one.&lt;/p&gt;
&lt;h2&gt;
  
  
  Setting up a Cloudinary account
&lt;/h2&gt;

&lt;p&gt;Visit the &lt;a href="https://cloudinary.com/?utm_source=hackmamba&amp;amp;utm_campaign=hackmamba-hackathon&amp;amp;utm_medium=hackmamba-blog"&gt;website&lt;/a&gt; to sign up for a free account, then set up your Cloudinary account. You can sign up using GitHub, Gmail, or your email address.&lt;/p&gt;

&lt;p&gt;After signing up, you will be required to choose a role. In this case, you should select &lt;strong&gt;Developer&lt;/strong&gt; and click continue.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--TjIO23gn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://paper-attachments.dropboxusercontent.com/s_8A36E5CB44728E01782AE054174F193D3039F956A7C8EB1077838B9C59DBBC11_1667335275895_cld-role.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--TjIO23gn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://paper-attachments.dropboxusercontent.com/s_8A36E5CB44728E01782AE054174F193D3039F956A7C8EB1077838B9C59DBBC11_1667335275895_cld-role.png" alt="" width="880" height="390"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, you will be asked to select what your project is most likely to be. Select the first option and click &lt;strong&gt;Done&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--XGIVtdcQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://paper-attachments.dropboxusercontent.com/s_8A36E5CB44728E01782AE054174F193D3039F956A7C8EB1077838B9C59DBBC11_1667335486847_cld-project.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XGIVtdcQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://paper-attachments.dropboxusercontent.com/s_8A36E5CB44728E01782AE054174F193D3039F956A7C8EB1077838B9C59DBBC11_1667335486847_cld-project.png" alt="" width="880" height="390"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Navigate to your &lt;strong&gt;dashboard&lt;/strong&gt;. The dashboard contains the account details, which is the most critical area of the project.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--K3JG7lsz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://paper-attachments.dropboxusercontent.com/s_8A36E5CB44728E01782AE054174F193D3039F956A7C8EB1077838B9C59DBBC11_1667336095733_cld-dashboard.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--K3JG7lsz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://paper-attachments.dropboxusercontent.com/s_8A36E5CB44728E01782AE054174F193D3039F956A7C8EB1077838B9C59DBBC11_1667336095733_cld-dashboard.png" alt="" width="880" height="387"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;By default, Cloudinary assigns a random &lt;strong&gt;cloud name&lt;/strong&gt; which you can edit to a name of your choice. To edit your cloud name, click on &lt;strong&gt;settings&lt;/strong&gt; (the clog icon at the top left corner) and scroll to the bottom of the page as seen below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vgSQ5EqQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://paper-attachments.dropboxusercontent.com/s_8A36E5CB44728E01782AE054174F193D3039F956A7C8EB1077838B9C59DBBC11_1667336306136_cld-settings.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vgSQ5EqQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://paper-attachments.dropboxusercontent.com/s_8A36E5CB44728E01782AE054174F193D3039F956A7C8EB1077838B9C59DBBC11_1667336306136_cld-settings.png" alt="" width="880" height="391"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Enter the cloud name of your choice and click &lt;strong&gt;Save&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Next, you need to set your upload preset. Still on your settings page, at the top of the page, click on &lt;strong&gt;Upload&lt;/strong&gt; and scroll down to the section below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Dynudr75--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://paper-attachments.dropboxusercontent.com/s_8A36E5CB44728E01782AE054174F193D3039F956A7C8EB1077838B9C59DBBC11_1667336975127_cld-upload.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Dynudr75--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://paper-attachments.dropboxusercontent.com/s_8A36E5CB44728E01782AE054174F193D3039F956A7C8EB1077838B9C59DBBC11_1667336975127_cld-upload.png" alt="" width="880" height="385"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click on &lt;em&gt;&lt;strong&gt;Add upload preset&lt;/strong&gt;&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9vzI2ew5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://paper-attachments.dropboxusercontent.com/s_8A36E5CB44728E01782AE054174F193D3039F956A7C8EB1077838B9C59DBBC11_1667337018993_cld-upload-preset.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9vzI2ew5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://paper-attachments.dropboxusercontent.com/s_8A36E5CB44728E01782AE054174F193D3039F956A7C8EB1077838B9C59DBBC11_1667337018993_cld-upload-preset.png" alt="" width="880" height="382"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Input your desired preset name, set the &lt;strong&gt;Signing mode&lt;/strong&gt; to &lt;strong&gt;Unsigned&lt;/strong&gt;, and click Save.&lt;/p&gt;

&lt;p&gt;Next, you will set up your Xata account.&lt;/p&gt;
&lt;h2&gt;
  
  
  Setting up the Xata account
&lt;/h2&gt;

&lt;p&gt;Visit the &lt;a href="https://xata.io/?utm_source=hackmamba&amp;amp;utm_campaign=hackmamba-hackathon&amp;amp;utm_medium=hackmamba-blog"&gt;website&lt;/a&gt; to register for free. You will see the &lt;strong&gt;&lt;em&gt;Add a database&lt;/em&gt;&lt;/strong&gt; card after signing up, where you will create your database.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QvlZGszw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://paper-attachments.dropboxusercontent.com/s_8A36E5CB44728E01782AE054174F193D3039F956A7C8EB1077838B9C59DBBC11_1667339508317_xata.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QvlZGszw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://paper-attachments.dropboxusercontent.com/s_8A36E5CB44728E01782AE054174F193D3039F956A7C8EB1077838B9C59DBBC11_1667339508317_xata.png" alt="" width="880" height="389"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click on the card, input your database name and click Create. A new card with your database name will appear next to the &lt;em&gt;&lt;strong&gt;Add a database&lt;/strong&gt;&lt;/em&gt; card.&lt;/p&gt;

&lt;p&gt;Next, you need to create a table. Select your new database to navigate a page like the one below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--u06uVdxP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://paper-attachments.dropboxusercontent.com/s_8A36E5CB44728E01782AE054174F193D3039F956A7C8EB1077838B9C59DBBC11_1667339469287_xata-table.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--u06uVdxP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://paper-attachments.dropboxusercontent.com/s_8A36E5CB44728E01782AE054174F193D3039F956A7C8EB1077838B9C59DBBC11_1667339469287_xata-table.png" alt="" width="880" height="385"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click on &lt;em&gt;&lt;strong&gt;Add a table&lt;/strong&gt;&lt;/em&gt; in the sidebar below and insert your table name. You can also populate your table by clicking the &lt;strong&gt;&lt;em&gt;Add a record&lt;/em&gt;&lt;/strong&gt; button and filling in the desired details.&lt;/p&gt;

&lt;p&gt;For this project, you will need three tables; Users, Stores, and Products.&lt;/p&gt;

&lt;p&gt;The &lt;em&gt;Users&lt;/em&gt; table should have the following columns:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;id&lt;/strong&gt;: The user's unique id auto-generated by xata&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;first_name&lt;/strong&gt;: The user's first name&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;last_name&lt;/strong&gt;: The user's last name&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;email&lt;/strong&gt;: The user's email&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;password&lt;/strong&gt;: The user's password&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;username&lt;/strong&gt;: The user's display name&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;em&gt;Products&lt;/em&gt; table should have the following columns:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;id&lt;/strong&gt;: Xata auto-generated id&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;name&lt;/strong&gt;: Name of product&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;price&lt;/strong&gt;: Price of the product&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;description&lt;/strong&gt;: Short description of the product&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;image_url&lt;/strong&gt;: Image URL gotten from Cloudinary&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;store_id&lt;/strong&gt;: The store id&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Finally, the &lt;em&gt;Store&lt;/em&gt; table should contain the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;id&lt;/strong&gt;: Xata auto-generated id&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;name&lt;/strong&gt;: Store name&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;owners_id&lt;/strong&gt;: User id&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Congratulations! You have completed the basic setup for Cloudinary and Xata. Next, you will insert and query data with Nextjs to Cloudinary and Xata.&lt;/p&gt;
&lt;h2&gt;
  
  
  Xata and Nextjs
&lt;/h2&gt;
&lt;h4&gt;
  
  
  Signing up users
&lt;/h4&gt;

&lt;p&gt;Go to &lt;code&gt;/pages/api/auth/register.ts&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { NextApiRequest, NextApiResponse } from "next";
import nc from "next-connect";
import { getXataClient } from "../../../utils/xata.codegen";


const xata = getXataClient();
const handler = nc().post(async (req: NextApiRequest, res: NextApiResponse) =&amp;gt; {
  const record = await xata.db.Users.filter({
    email: req.body.email
  }).getMany();
  if (record.length !== 0) {
    res.status(403);
    res.end();
    return;
  } else {
    console.log(req.body)
    const user = await xata.db.Users.create({
      ...req.body,
    });
    return res.status(200).json({ data: user });
  }
});
export default handler;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;The above code performs authentication for users when they try to sign up. First, the &lt;code&gt;Users&lt;/code&gt; table is queried from the database and then filtered based on the email gotten from the client side. The result will be an array that is passed to the &lt;code&gt;record&lt;/code&gt; variable.&lt;/p&gt;

&lt;p&gt;Then we check if the record contains any data using &lt;code&gt;record.length&lt;/code&gt;. If true, we parse a 403 error code and end the process. If false, we proceed to create a new user.&lt;/p&gt;
&lt;h4&gt;
  
  
  Log in users
&lt;/h4&gt;

&lt;p&gt;Go to &lt;code&gt;/pages/api/auth/login.ts&lt;/code&gt;&lt;code&gt;.&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { NextApiRequest, NextApiResponse } from "next";
import nc from "next-connect";
import Router from "next/router";
import { getXataClient } from "../../../utils/xata.codegen";

const xata = getXataClient();
const handler = nc().post(async (req: NextApiRequest, res: NextApiResponse) =&amp;gt; {
  const record = await xata.db.Users.filter({
    email: req.body.email,
  }).getMany();

  if (!record) {
    return res.status(401).json({ message: "Invalid email/password" });
  } else if (record[0].password !== req.body.password) {
    return res.status(401).json({ message: "Invalid email/password" });
  } else {
    return res.status(200).json({ data: record });
  }
});
export default handler;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Like the sign-up page, the Users table is also queried and filtered for the login page. If no data is found, an error message is passed. If a record is found, we parse the data.&lt;/p&gt;
&lt;h4&gt;
  
  
  Create a store
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;/pages/api/store/index.ts&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { NextApiRequest, NextApiResponse } from "next";
import nc from "next-connect";
import { getXataClient } from "../../../utils/xata.codegen";
import { decode } from "jsonwebtoken";
const xata = getXataClient();
const handler = nc().post(async (req: NextApiRequest, res: NextApiResponse) =&amp;gt; {
  const { name }: { name: string } = req.body;
  const jwt = req.cookies.frontier__jwt;
  const decodedData = decode(jwt);
  const accessToken = decodedData["0"].id;

  const record = await xata.db.Store.create({
    owners_id: accessToken,
    name: name,
  });
  if (!accessToken &amp;amp;&amp;amp; record) {
    res.end();
    return;
  }
  res.status(200).json({
    data: record,
  });
});
export default handler;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;To create a store, the above code retrieves the user's (owner) id encoded with JSON web token (JWT) and passes it along with the desired store name.&lt;/p&gt;
&lt;h4&gt;
  
  
  Fetch user store
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;/pages/api/products/index.ts&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { NextApiRequest, NextApiResponse } from "next";
import nc from "next-connect";
import { getXataClient } from "../../../utils/xata.codegen";
const xata = getXataClient();
import { decode } from "jsonwebtoken";
const handler = nc().get(async (req: NextApiRequest, res: NextApiResponse) =&amp;gt; {
  const jwt = req.cookies.frontier__jwt;
  const decodedData = decode(jwt);
  const accessToken = decodedData["0"].id;
  const record = await xata.db.Store.filter({
    owners_id: accessToken,
  }).getMany();
  if (!record) {
    res.end();
    return;
  }
  res.status(200).json({
    data: record,
  });
});
export default handler;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;The code above filters the Store table by the user's id and returns every store owned by the user.&lt;/p&gt;
&lt;h4&gt;
  
  
  Post a product
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;/pages/api/store/index.ts&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { NextApiRequest, NextApiResponse } from "next";
import nc from "next-connect";
import { getXataClient } from "../../../utils/xata.codegen";
const xata = getXataClient();
const handler = nc().post(async (req: NextApiRequest, res: NextApiResponse) =&amp;gt; {
  console.log(req.body);
  const product = xata.db.Products.create({ ...req.body });
  console.log(product);
  return res.status(200).json({ data: product });
});
export default handler;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;To create a product, the above code passes the information sent from the client form.&lt;/p&gt;
&lt;h4&gt;
  
  
  Fetch user product
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;/pages/api/stores/index.ts&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { NextApiRequest, NextApiResponse } from "next";
import nc from "next-connect";
import { getXataClient } from "../../../utils/xata.codegen";
const xata = getXataClient();
const handler = nc().post(async (req: NextApiRequest, res: NextApiResponse) =&amp;gt; {
  const { storeID } = req.body;
  const record = await xata.db.Products.filter({
    store_id: storeID,
  }).getMany();
  if (!record) {
    res.end();
    return;
  }
  res.status(200).json({
    data: record,
  });
});
export default handler;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;The code above filters the Product table based on the store's id and returns every product owned by the store.&lt;/p&gt;
&lt;h2&gt;
  
  
  Cloudinary and Nextjs
&lt;/h2&gt;
&lt;h4&gt;
  
  
  Uploading file to Cloudinary
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;/pages/app/products/new/index.ts&lt;/code&gt;&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;The above code aids in passing the image file to Cloudinary. The &lt;code&gt;handleFileChange()&lt;/code&gt; function sets the &lt;code&gt;file&lt;/code&gt; state with the image file from the input field. After filling in other fields, the submit button calls the &lt;code&gt;handleSubmit()&lt;/code&gt; function when clicked. The &lt;code&gt;formData&lt;/code&gt; is used to construct a set of key/value pairs representing the required field for uploading media to Cloudinary.&lt;/p&gt;

&lt;p&gt;Then a POST request is made, passing the &lt;code&gt;cloudinary_url&lt;/code&gt;, along with the &lt;code&gt;formData&lt;/code&gt;. The response is parsed, and the URL for the image is set to state &lt;code&gt;image_url&lt;/code&gt;. Next, all the information from the form is passed to the server side using the &lt;code&gt;product()&lt;/code&gt; function, where they are inserted into the Product table.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping up
&lt;/h2&gt;

&lt;p&gt;In this article, you learned how to set up and use Cloudinary to upload and store media files and Xata to query data from your Nextjs project. You also learned how to configure Xata on your project using the CLI. Remember the project is available and accessible on GitHub.&lt;/p&gt;

&lt;h2&gt;
  
  
  Project Demo
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--iKY_mqQ7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://www.dropbox.com/s/ejbbppanqc14sur/screen-capture.gif%3Fraw%3D1" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--iKY_mqQ7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://www.dropbox.com/s/ejbbppanqc14sur/screen-capture.gif%3Fraw%3D1" alt="" width="880" height="355"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can check out the &lt;a href="https://frontier-xi.vercel.app/"&gt;live application&lt;/a&gt; to get a feel for how the application works. &lt;/p&gt;

&lt;h2&gt;
  
  
  Project Contributors
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Akunne Pascal&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/Kodecheff"&gt;GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://twitter.com/meta_khal"&gt;Twitter&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Harcourt Hamsa&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/HarcourtHamsa"&gt;GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://twitter.com/harcourt_hamsa"&gt;Twitter&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>nextjs</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Article Banner: Created with React and Auth0</title>
      <dc:creator>Akunne Pascal</dc:creator>
      <pubDate>Sat, 16 Oct 2021 22:53:00 +0000</pubDate>
      <link>https://dev.to/hackmamba/article-banner-created-with-react-and-auth0-1pjk</link>
      <guid>https://dev.to/hackmamba/article-banner-created-with-react-and-auth0-1pjk</guid>
      <description>&lt;p&gt;This project is created with React.js and uses Auth0 for authentication. So in this article, we will discuss on how to use the application.&lt;/p&gt;

&lt;h3&gt;
  
  
  Challenges
&lt;/h3&gt;

&lt;p&gt;Before we talk about the project, let me briefly highlight the challenge I encountered. This is actually not a complete project, in that I plan on adding a &lt;code&gt;Generate link&lt;/code&gt; button so users can either download the banner or generate a link instead. This is where Cloudinary comes in.&lt;/p&gt;

&lt;p&gt;In using cloudinary, the traditional way of uploading media to their server is via a form. But for this project, form is not used, rather an NPM package (html2canvas) is used to generate the banner image. If you know a way I can upload canvas image to cloudinary without using the form, please leave a comment.&lt;/p&gt;

&lt;p&gt;We won't cover the entirety of the project, just the important part, so I will try to make this article as brief as possible. You can clone the &lt;a href="https://github.com/kodecheff/banner-generator"&gt;source code&lt;/a&gt; to your device. Now let's dive right in!&lt;/p&gt;

&lt;p&gt;After cloning the project to your device, open the project on your IDE (e.g visual studio) to start.&lt;/p&gt;

&lt;h3&gt;
  
  
  Registering on Auth0
&lt;/h3&gt;

&lt;p&gt;First off, you will need to create an account on Auth0. Visit &lt;a href="https://auth0.com/"&gt;Auth0&lt;/a&gt; to register your account.&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating a tenant
&lt;/h3&gt;

&lt;p&gt;You will create a tenant after successfully signing up. The tenant is where you configure your Auth0 usage and where Auth0 assets like applications, connections, and user profiles are defined, managed, and stored. It is immutable.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8kaxcZeF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8otdpc341i10qqt0z9nj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8kaxcZeF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8otdpc341i10qqt0z9nj.png" alt="Create auth0 tenant"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Creating an application
&lt;/h3&gt;

&lt;p&gt;From your dashboard, click on applications &amp;gt; applications. Then click on create application. A box will appear as seen below, where will be required to enter your application name and select your application type.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NSBwv0EE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6qmxs6jci7h75bgdmahh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NSBwv0EE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6qmxs6jci7h75bgdmahh.png" alt="create auth0 application"&gt;&lt;/a&gt;&lt;br&gt;
Auth0 will assign you an immutable client ID which you will use in your code to call the Auth0 API. To get your client ID, select your application, and go to settings.&lt;/p&gt;
&lt;h3&gt;
  
  
  Environmental Variable
&lt;/h3&gt;

&lt;p&gt;On the root folder of your project, create a &lt;code&gt;.env&lt;/code&gt; file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    REACT_APP_AUTH0_DOMAIN= /* domain */
    REACT_APP_AUTH0_CLIENT_ID= /* client id */
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Copy your &lt;code&gt;Domain&lt;/code&gt; and &lt;code&gt;Client ID&lt;/code&gt; values from your application settings and paste them in your &lt;code&gt;.env&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;Run the following command in your terminal to install dependencies&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    npm install
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your dependencies can be found in the &lt;code&gt;package.json&lt;/code&gt; file.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using Auth0
&lt;/h2&gt;

&lt;p&gt;Auth0 is platform that creates an easy to implement, adaptable authentication and authorization for your application. In this section, I will explain how the Auth0 authentication is used in different components of the application.&lt;/p&gt;

&lt;h3&gt;
  
  
  Integrating Auth0
&lt;/h3&gt;

&lt;p&gt;To integrate Auth0 to your react application, you will use the Auth0 React SDK &lt;code&gt;@auth0/auth0-react&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Run the command&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    npm install --save @auth0/auth0-react
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;auth-history.js&lt;/strong&gt;&lt;br&gt;
Go to &lt;code&gt;/src/auth/auth-history.js&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    import React from "react";
    import { useHistory } from "react-router-dom";
    import { Auth0Provider } from "@auth0/auth0-react";
    const AuthHistory = ({ children }) =&amp;gt; {
      const domain = process.env.REACT_APP_AUTH0_DOMAIN;
      const clientId = process.env.REACT_APP_AUTH0_CLIENT_ID;
      const history = useHistory();
      const onRedirectCallback = (appState) =&amp;gt; {
        history.push(appState?.returnTo || window.location.pathname);
      };
      return (
        &amp;lt;Auth0Provider
          domain={domain}
          clientId={clientId}
          redirectUri={window.location.origin}
          onRedirectCallback={onRedirectCallback}
        &amp;gt;
          {children}
        &amp;lt;/Auth0Provider&amp;gt;
      );
    };
    export default AuthHistory;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To process authentication, the Auth0 React SDK connects to the Auth0 Application. The &lt;code&gt;Auth0Provider&lt;/code&gt; must be configured with an Auth0 Domain and Client ID.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;onRedirectCallback()&lt;/code&gt; method is called when Auth0 redirects users from the Auth0 Universal Login page to the application. The &lt;code&gt;useHistory()&lt;/code&gt; hook is used to retrieve the React Router's history object. The &lt;code&gt;history.push()&lt;/code&gt; method will then redirect users to the route they intended to visit prior to authentication.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;index.js&lt;/strong&gt;&lt;br&gt;
Go to &lt;code&gt;src/index.js&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    import React from 'react';
    import ReactDOM from 'react-dom';
    import './index.css';
    import App from './App';
    import {BrowserRouter as Router} from 'react-router-dom'
    import AuthHistory from './auth/auth-history'


    ReactDOM.render(
      &amp;lt;Router&amp;gt;
        &amp;lt;AuthHistory&amp;gt;
          &amp;lt;App /&amp;gt;
        &amp;lt;/AuthHistory&amp;gt;
      &amp;lt;/Router&amp;gt;,
      document.getElementById("root")
    );
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;App&lt;/code&gt; component is wrapped with the &lt;code&gt;AuthHistory&lt;/code&gt; component so that the entire application will have access to the &lt;code&gt;AuthContext&lt;/code&gt;. The &lt;code&gt;BrowserRouter&lt;/code&gt; component from React Router must be the parent of the &lt;code&gt;AuthHistory&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;LoginButton.js&lt;/strong&gt;&lt;br&gt;
Go to &lt;code&gt;/src/components/buttons/loginbutton.js&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    import React from "react";
    import { useAuth0 } from "@auth0/auth0-react";
    const LoginButton = () =&amp;gt; {
      const { loginWithRedirect } = useAuth0();
      return &amp;lt;button className="btn btn-primary btn-block" onClick={() =&amp;gt; loginWithRedirect()}&amp;gt;Log In&amp;lt;/button&amp;gt;;
    };
    export default LoginButton;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When &lt;code&gt;loginWithRedirect()&lt;/code&gt; method is called, a user is asked to authenticate and give permission for the application to access specific data on their behalf. This means that the application redirects the user to the Auth0 Universal Login page to complete the authentication process.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SignupButton.js&lt;/strong&gt;&lt;br&gt;
Go to &lt;code&gt;/src/components/buttons/signupbutton.js&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    import React from "react";
    import { useAuth0 } from "@auth0/auth0-react";
    const SignupButton = () =&amp;gt; {
      const { loginWithRedirect } = useAuth0();
      return (
        &amp;lt;button
          className="btn btn-primary btn-block m-2"
          onClick={() =&amp;gt;
            loginWithRedirect({
              screen_hint: "signup",
            })
          }
        &amp;gt;
          Sign Up
        &amp;lt;/button&amp;gt;
      );
    };
    export default SignupButton;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the signup component, an option is passed to redirect users to an Auth0 Universal Login page optimized for signing up for the application. This is done by specifying the &lt;code&gt;screen_hint=signup&lt;/code&gt; property in the configuration object of &lt;code&gt;loginWithRedirect()&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;LogoutButton.js&lt;/strong&gt;&lt;br&gt;
Go to &lt;code&gt;/src/components/buttons/logoutbutton.js&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    import React from "react";
    import { useAuth0 } from "@auth0/auth0-react";
    const LogoutButton = () =&amp;gt; {
      const { logout } = useAuth0();
      return (
        &amp;lt;button
          className="btn btn-danger btn-block"
          onClick={() =&amp;gt;
            logout({
              returnTo: window.location.origin,
            })
          }
        &amp;gt;
          Log Out
        &amp;lt;/button&amp;gt;
      );
    };
    export default LogoutButton;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Auth0Context's &lt;code&gt;logout()&lt;/code&gt; method clears the application session and redirects to the Auth0 &lt;code&gt;/v2/logout&lt;/code&gt; endpoint to clear the Auth0 session. &lt;code&gt;logout()&lt;/code&gt;, like the login method, accepts an object argument to define parameters for the &lt;code&gt;/v2/logout&lt;/code&gt; call. The &lt;code&gt;returnTo&lt;/code&gt; option specifies the URL to which Auth0 should redirect users after they logout.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AuthenticateButton.js&lt;/strong&gt;&lt;br&gt;
Go to &lt;code&gt;/src/components/buttons/authenticatebutton.js&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    import React from "react";
    import LoginButton from "./LoginButton";
    import LogoutButton from "./LogoutButton";
    import SignupButton from './SignupButton'
    import { useAuth0 } from "@auth0/auth0-react";
    const AuthenticationButton = () =&amp;gt; {
      const { isAuthenticated } = useAuth0();
      return isAuthenticated ? &amp;lt;LogoutButton /&amp;gt; : (
        &amp;lt;div&amp;gt;
          &amp;lt;SignupButton className="mr-5 " /&amp;gt;
          &amp;lt;LoginButton /&amp;gt;
        &amp;lt;/div&amp;gt;
      );
    };
    export default AuthenticationButton;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;isAuthenticated&lt;/code&gt; is used to check if a user is logged in. It returns a boolean &lt;code&gt;true&lt;/code&gt; is logged in. If a user is authenticated, it displays the &lt;code&gt;logout&lt;/code&gt; button, if not authenticated, the &lt;code&gt;signup&lt;/code&gt; and &lt;code&gt;login&lt;/code&gt; buttons are displayed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;BannerWrapper&lt;/strong&gt;&lt;br&gt;
Go to &lt;code&gt;src/components/bannerwrapper/index.js&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    ...
    const { isAuthenticated } = useAuth0();
      return (
        &amp;lt;&amp;gt;
          &amp;lt;div className="wrapper"&amp;gt;
            &amp;lt;div&amp;gt;
              &amp;lt;Output values={values} /&amp;gt;
            &amp;lt;/div&amp;gt;
            &amp;lt;div className="actionWrapper"&amp;gt;
              &amp;lt;InputWrapper values={values} setters={setters} /&amp;gt;
              { isAuthenticated ? (
                &amp;lt;&amp;gt;
                  &amp;lt;button className="btn btn-success mb-5 mt-3" id="download-button" download="banner.png" href={imgURL}&amp;gt;
                    &amp;lt;a download="banner.png" href={imgURL}&amp;gt;DOWNLOAD BANNER&amp;lt;/a&amp;gt;
                  &amp;lt;/button&amp;gt;
                &amp;lt;/&amp;gt;
              ) : (
                &amp;lt;h5 className="mb-5 mt-3" style={{color: "red"}}&amp;gt;Login to download your banner&amp;lt;/h5&amp;gt;
              )}
            &amp;lt;/div&amp;gt;
          &amp;lt;/div&amp;gt;
        &amp;lt;/&amp;gt;
      )
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this part of the &lt;code&gt;bannerWrapper&lt;/code&gt; component, the &lt;code&gt;isAuthenticated&lt;/code&gt; is used once more to check if user is logged in. If authenticated, the &lt;code&gt;download&lt;/code&gt; button will be displayed. If not authenticated, a red-colored text is displayed requesting the user to login in order to download the banner.&lt;/p&gt;

&lt;p&gt;That is how Auth0 is used in this project application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Overview of the application
&lt;/h2&gt;

&lt;p&gt;Now run the following command to start the project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    npm start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your browser should display the following image&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--omxFaB57--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/englj3zj9cnw2frmalk5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--omxFaB57--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/englj3zj9cnw2frmalk5.png" alt="banner display"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At the bottom of the page, your will see a red-colored sentence, requesting you to login before you can download your banner. Since your are a new user, you will have to signup instead. So click on the signup button to register.&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZHXpCEmY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/77pn1lflh177h6lqinbk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZHXpCEmY--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/77pn1lflh177h6lqinbk.png" alt="banner signup"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Fill in your email address and password to signup or your can simply signup with Google. When signed in, you will be presented access to the download button, so your can easily download your banner to your device.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--s_Trlbal--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jf9ns35ssxqx1eglxo9x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--s_Trlbal--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/jf9ns35ssxqx1eglxo9x.png" alt="banner logged in"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;With Auth0, we can easily implement an adaptable authentication and authorization for our application. While with Cloudinary, we can manage our cloud-based media services such as image and video. It enables users to upload, store, manage, manipulate, and deliver images and video for websites and apps.&lt;/p&gt;

&lt;p&gt;These are robust technologies that can make our development easier and faster.&lt;/p&gt;

&lt;p&gt;Here is a link to my live demo on &lt;a href="https://codesandbox.io/s/elastic-pateu-0f0gj"&gt;codesandbox&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Reference
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://auth0.com/docs/quickstart/spa/react"&gt;https://auth0.com/docs/quickstart/spa/react&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://auth0.com/docs/get-started"&gt;https://auth0.com/docs/get-started&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://auth0.com/blog/complete-guide-to-react-user-authentication/"&gt;https://auth0.com/blog/complete-guide-to-react-user-authentication/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Content created for the Hackmamba Jamstack Content Hackathon using Auth0 and Cloudinary&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
