How to Create a Resume Builder App with Xata and Cloudinary Using NextJs
Tags: javascript, jamstack, xata, nextjs
Published: 2022-11-23 08:14:27

## Introduction

Resumes play an essential role in getting a job, as it aids in ascertaining a candidate's level of competency for a job role. That said, it needs to be built with care. 

In this article, we will learn how to use [](https://xata.io/)[Xata](https://xata.io/?utm_source=hackmamba&utm_campaign=hackmamba-hackathon&utm_medium=hackmamba-blog), a serverless, branch-able, scalable, consistent, highly available, searchable database to build a resume builder’s backend, and [](https://cloudinary.com/)[Cloudinary](https://cloudinary.com/?utm_source=hackmamba&utm_campaign=hackmamba-hackathon&utm_medium=hackmamba-blog), a cloud-based asset management service, to manage all assets. At the same time, [](https://nextjs.org/)[Next.js](https://nextjs.org/) will be used to handle the front-end development.


[Here’s a sneak peek at what we’ll be building](https://quickcvnow.netlify.app/)

The source code of the project is available [here on GitHub](https://github.com/femakin/XaTaHackMambaHackathon.git)

Here is a working demo on [CodeSandbox](https://codesandbox.io/s/infallible-archimedes-50o0y3?file=/pages/index.js)


## Project Demo

The video below shows what we will be building in this article.


{% youtube https://www.youtube.com/watch?v=by6f6_vwgwI& %}


## Why Xata and Cloudinary

[Xata](https://xata.io/?utm_source=hackmamba&utm_campaign=hackmamba-hackathon&utm_medium=hackmamba-blog) allows us to combine a Serverless Relational Database, a search engine, and an analytics engine, all behind a single consistent API. There’s also support for edge caching, a workflow for zero-downtime schema migration, and first-class branch support.
At the same time, [Cloudinary](https://cloudinary.com/?utm_source=hackmamba&utm_campaign=hackmamba-hackathon&utm_medium=hackmamba-blog) gives us a lot of power to optimize and transform images automatically, which makes it easy to build any application.

## Prerequisites

To follow along, we will need the following:

1. Basic knowledge of [Next.js](https://nextjs.org/).
2. Basic knowledge of [JavaScript](https://developer.mozilla.org/en-US/docs/Web/JavaScript)/[TypeScript](https://www.typescriptlang.org/docs/)
3. [Node.js](https://nodejs.org/en/) installed.

## Project Overview

In this project, we will examine how Xata works as a serverless database that can power the backend of any application. Also, to explore the beauty of assets management Cloudinary has to offer.

Below are the packages we will use in this project:


1. [Next.js](https://nextjs.org/): A React Framework to build our Frontend.
2. [Xata](https://xata.io/?utm_source=hackmamba&utm_campaign=hackmamba-hackathon&utm_medium=hackmamba-blog): A Serverless Data Platform to build our backend
3. [Cloudinary](https://cloudinary.com/?utm_source=hackmamba&utm_campaign=hackmamba-hackathon&utm_medium=hackmamba-blog): To power and manage our assets.
4. [Tailwind CSS](https://tailwindcss.com/): A utility-first CSS framework to support and develop our design
5. [React-Hook-Form](https://www.react-hook-form.com/): To handle all our form input
6. [React Icons](https://react-icons.github.io/react-icons/): To add beautiful Icons to our pages.
7. [Base64](https://www.base64encode.org/): Passwords are encoded using Base64.
8. [ReactToPrint](https://www.npmjs.com/package/react-to-print): To print our components in the browser
9. [jsPDF](https://www.npmjs.com/package/jspdf): A library to generate our PDFs in JavaScript.
10. [Yup](https://www.npmjs.com/package/yup): A JavaScript schema builder to parse and validate our form input values.
11. [React-hook-form validation resolver](https://www.npmjs.com/package/@hookform/resolvers): A JavaScript schema builder to parse and validate our form input values.
12. [HeroIcons](https://www.npmjs.com/package/@heroicons/react)

## Project Pages

In the Project, we will have the following Pages

1. Home/Landing Page
2. Signup Page
3. Login Page
4. Dashboard Page
- My Resume Page
    - Edit Resume
    - Download Resume
- Create Resume Page


## Getting Started

In this section, we will be doing the following:


1. Creating a Database on Xata
2. Building the front end with Next.js
3. Cloudinary Setup
4. Linking our Database with our Frontend and Cloudinary
5. Deploying Our App to Netlify


## Creating a Database on Xata

To create our Database, we need to login into our  [Xata dashboard](https://app.xata.io/signin?callbackUrl=https%3A%2F%2Fapp.xata.io%2Fworkspaces&error=SessionRequired?utm_source=hackmamba&utm_campaign=hackmamba-hackathon&utm_medium=hackmamba-blog) 
by clicking any preferred login option

![Sign In Button](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kgr0ocipikx2wq2illut.png)


After logging into our dashboard, click on the **Add a database** button to create a database.

Clicking the Add a database button, we can now specify the name and location of our database.


![Workspace Image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nsspiyjrhr7skmmvjn5e.png)



![add database](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wffyptc8upcm7mrrmdj0.png)


For this project, we will name our database “basic_info,” as shown in the image below. We can change it to any other name if we want.

![database](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fl967fqq3hsb6vdhva8b.png)


**Creating tables**

Now, we need to create the tables for our project. In our project, we will need two tables, namely:

1. basic_info
2. user table

Xata represents data as tables, columns, and rows. Schemas describe this structure. Click on "+ Add a Table" and enter a name to add a table.

![Created table](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nhuxiiupxuvpf7rylsvf.png)


**Defining schema**
We can now define our project schema for our table by clicking the **“+”** icon on the table header. By default, all tables contain one column: the ID column, which gives each row a unique identifier. It can have any value that is unique across all rows of data.
In adding columns, we find that each column has various types. 

We will use string throughout our project schemas, as shown below.

The User table looks like this after we have created our schema columns.

![schema columns](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hpsuho9gy3qm7rf8lyk9.png)


In our basic_info table, we need to create our schema columns with the names:


{% gist https://gist.github.com/femakin/3f858024112d6df4b7b0c1c087334b7d %}



![schema columns](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hyq53smvbzr7ke763noi.png)


**Working with our data**
We are now ready to process requests for data from clients and insert incoming data into our database after setting it up as described above.
To look at how we can use our data, we now have to proceed to step two under the Getting started above: Building our front end with Next.js.

## Building the front end with Next.js

For fast development, we will clone the [Example repo](https://github.com/vercel/next.js/tree/canary/examples/with-xata) from Xata.
This example showcases how to use Next.js with Xata as our data layer.
With this template, we will get out-of-the-box:


1. API Route to connect to your Xata database
2. Type-safe Codegen
3. Accessibility-Ready
- Dark/Light mode
- Respect prefers-reduce-motion for CSS Transitions

**Bootstrapping our Next.js App**

To proceed, we copy the command below and paste it into our project folder in the terminal to bootstrap the Xata Example repo.


    npx create-next-app --example with-xata with-xata-app

Now, we can navigate to the project directory by running the following:


     cd with-xata-app

Also, we can type `git clone` and then paste the URL below to clone the example repo.


    git clone https://github.com/vercel/next.js.git

then we navigate into the project directory by running:


    cd next.js

then

    cd examples

then

    cd with-xata

**Linking Xata Workspace and Running Codegen**

The next step is to link our Xata Database to our client side. To accomplish this, we need to install [Xata CLI](https://xata.io/docs/cli/getting-started?utm_source=hackmamba&utm_campaign=hackmamba-hackathon&utm_medium=hackmamba-blog)
It will help us manage our databases more effectively.

To install the Xata CLI globally, we run the command below:


    npm i --location=global @xata.io/cli

To use the Xata CLI, we need to authenticate it to access our workspace and database. We will be doing this globally by running the following:


    xata auth login

In our terminal.

Using the `xata auth login` gives us two options:


1. **To create a new API Key:** This will open our browser and when we’re logged in, Xata allows us to create a new API key for use with the CLI.
    
2. **Use an existing API Key:** This will prompt for an existing key we have, which we can paste into our terminal. We will go with the first option for this project, creating a new API key.

Upon providing an API key, a global configuration of the CLI will be made, which stores our API key in 

`~/.config/xata/credentials`.

Now that we know all the steps to set up our Xata CLI let us run Xata auth login in our terminal using the code below.


    xata auth login

Here is what our project folders should look like

![folder structure](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s2rzx7b0oy5cbgusrh71.png)


**Installation**
The next step is to install all the packages we will use for our project, starting with Tailwind CSS by following the [Installation guild here](https://tailwindcss.com/docs/installation)
Next is to install other packages listed above by running the below command in our terminal


    npm install react-hook-form react-icons base-64 react-to-print jspdf yup 

It is essential to verify the dependencies in the package.json file to confirm whether they have been installed.

This should be the current state of our dependencies.

![dependencies](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/u5zxidl18ez5ssitu4ex.png)

## Cloudinary setup

To set up our Cloudinary account, we must follow the Cloudinary React image transformations documentation in this [guide](https://cloudinary.com/documentation/react_image_transformations?utm_source=hackmamba&utm_campaign=hackmamba-hackathon&utm_medium=hackmamba-blog)

Next is to install Cloudinary React, which allows us to quickly and easily integrate our application with Cloudinary and Cloudinary `URL-gen`. This enables us to create Cloudinary URLs for our images and videos by running the command below:


    npm i cloudinary-react @cloudinary/url-gen 


## Linking our Database with our Frontend and Cloudinary

**Our Components** 
Below is the list of components we will use in our project:


{% gist https://gist.github.com/femakin/2e10418a1bf7de7dd6ec46d31453f443 %}


**Download.jsx** 

 Here is our preview resume component.


{% gist https://gist.github.com/femakin/718843befb3bce30c7ba9cc3913bc40b %}



**DownloadandPreview.jsx**

This is our Download and Edit component Button


{% gist https://gist.github.com/femakin/1ad98e9cd20df2a00173601955940066 %}


**Education Component**

This is the Education section in our resume


{% gist https://gist.github.com/femakin/99460d51dc89d53e1460a67eaba2437b %}



**E****xtras.js**

This is the Extras section of our resume


{% gist https://gist.github.com/femakin/73268eec45fb25e5c154496ff0577143 %}



**Imagesandmedia.js**

This is the Image and media section of our resume


{% gist https://gist.github.com/femakin/d1862ffe4e7cf7d906617b88d8ba9f29 %}


**Interest.js**

This is the Interest section of our resume


{% gist https://gist.github.com/femakin/92fddfe454613af570ca34ef914d968e %}


**Nav.jsx** 

Nav Section of our pages 


{% gist https://gist.github.com/femakin/42a5b77ab69795d1724d935939ba50ae %}


**References.js** 

Reference Section of our Resume 


{% gist https://gist.github.com/femakin/119dd547e33e5ae3012a44cfa957a2cf %}


**Skills.js** 

Skills Section of our Resume 


{% gist https://gist.github.com/femakin/d991f8ea100619b3570b970d59e07ba3 %}


**TopMenu.jsx**

Top Menu section of our Resume


{% gist https://gist.github.com/femakin/d6dc0b62308d56e15faa8bf07dbff0da %}


The next folder is our context folder, which has the following structure:


{% gist https://gist.github.com/femakin/dff70ff266723e231fd1148784442937 %}


Inside our ***globalContext.jsx***, we have 


{% gist https://gist.github.com/femakin/1b87b92a896bb598f199b062f8a70c44 %}


and **signupContext.jsx** , we have 


{% gist https://gist.github.com/femakin/cd54c48dbe59a60095d478d0fc3c2237 %}


After creating our components and state context, we can move on to creating our project APIs, which have the following structure.


{% gist https://gist.github.com/femakin/209c0664ae8f601760d517fd2ac4e719 %}


**edit.js** 
This handles our CV editing


{% gist https://gist.github.com/femakin/fe81959f56bfe68e4a865abd7d449e28 %}


**fetchall.js**
Fetch all user API


{% gist https://gist.github.com/femakin/2e7b2b8308f69963d87e12c2cd867ffc %}


**getuser**
Get all user's API

{% gist https://gist.github.com/femakin/9a23bcb2ddef0500aa66d859dea01e6e %}

 
**signup.js** 
Signup API


{% gist https://gist.github.com/femakin/6760cb422f9c6e3630e9afdd2438b4c2 %}


**upload.js**
This handle or CV Form creation

{% gist https://gist.github.com/femakin/9d12f47c32e15e7ef9c08adc65d121cb %}


**Our Pages**
Also, most of the content here will be code snippets from our code. Please find the code [here](https://github.com/femakin/XaTaHackMambaHackathon.git) on GitHub.

**Pages Structure** 


{% gist https://gist.github.com/femakin/44894a9316631f6e730fd904a9e168d1 %}


**index.js** 

**Our landing pages**


{% gist https://gist.github.com/femakin/0a6647ec0c09131cb5522496249a716f %}


**signup.js** 


{% gist https://gist.github.com/femakin/e86e57a61996fa49833bf743ffcb8eff %}


**login.jsx** 


{% gist https://gist.github.com/femakin/ed4be1d470ac008f53f6444a0d361121 %}


**stepone.jsx** 

**Dashboard.jsx** 


{% gist https://gist.github.com/femakin/9f647674250aaa138619a6832c3c5c9d %}


steptwo.jsx

**Edit Page** 


{% gist https://gist.github.com/femakin/55d382e25e614cd88c6216d890820e96 %}


**Preview.jsx**

The page to download our Resume


{% gist https://gist.github.com/femakin/e0bcbc74ee1d630903ab9658a1f0c958 %}


**Our Stylesheets**

Also, most of the content here will be code snippets from our code. Please find the code [here](https://github.com/femakin/XaTaHackMambaHackathon.git) on GitHub.

Pages Structure


{% gist https://gist.github.com/femakin/08cacd6d78b670475883ed4cd3bcdf30 %}


**Home.module.css** 


{% gist https://gist.github.com/femakin/facf1690cbe01333dbe160d04d1395ec %}


Nav**.module.css**



{% gist https://gist.github.com/femakin/53e92bcdfdc982519a285a82fe89b6f8 %}


**Preview.module.css** 


{% gist https://gist.github.com/femakin/c94c4c9461e6744b3be7b98dcf571fbc %}



**root.module.css**


{% gist https://gist.github.com/femakin/e7ae4800f612364709729cafcf2821f3 %}



**Signup.module.css**


{% gist https://gist.github.com/femakin/4ef99c3f29fbd730b93c8471a2c1253e %}


**steptwo.module.css**



{% gist https://gist.github.com/femakin/2a12542a36e287c99e3818f4d6f7163b %}



## **Deploying Our App to Netlify**

Our app must now be deployed to Netlify using this [guide](https://www.netlify.com/blog/2020/11/30/how-to-deploy-next.js-sites-to-netlify/?utm_source=hackmamba&utm_campaign=hackmamba-hackathon&utm_medium=hackmamba-blog) after we have linked our front end to our database.


## Conclusion

This post discussed creating a Resume Builder App with Xata and Cloudinary Using NextJs. I hope you enjoyed reading this article. 

Here is a list of what we did in this article 


1. Set up a Next.js project.
2. Make use of Xata for backend services
3. Manage assets with Cloudinary
4. Use CSS and Tailwind CSS in a Next.js project
5. Manage state using the Context API in a Next.js project.
6. Use NPM packages Project Overview.


## Resources and References

These resources might be helpful:


- [Xata doc](https://xata.io/docs/overview?utm_source=hackmamba&utm_campaign=hackmamba-hackathon&utm_medium=hackmamba-blog)
- [Cloudinary Image transformations with React](https://cloudinary.com/documentation/react_image_transformations?utm_source=hackmamba&utm_campaign=hackmamba-hackathon&utm_medium=hackmamba-blog)
- [How to Deploy Next.js Sites to Netlify](https://www.netlify.com/blog/2020/11/30/how-to-deploy-next.js-sites-to-netlify/)