Handling images with Cloudinary in React
Tags: react
Published: 2020-05-22 19:33:23

---
title: Handling images with Cloudinary in React
published: true
date: 2020-05-07 16:00:58 UTC
tags: react
canonical_url: https://blog.logrocket.com/handling-images-with-cloudinary-in-react/
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/n7vyx9ex9wjjlzjx1vp6.png
---
**Written by [Nedy Udombat](https://blog.logrocket.com/author/nedyudombat/)**✏️

## Introduction

Sometimes while working on applications that require the use of images, a simple process like uploading images to a server can become difficult. With Cloudinary, we can upload and manage our images directly from the frontend. In this blog post, we will be taking a look at how to handle images in our React applications with the use of Cloudinary.

## Prerequisites

- Basic knowledge of JavaScript
- Basic knowledge of React
- The latest version [Node.js](https://nodejs.org/en/) installed on your machine
- A terminal such as [ITerm2](https://iterm2.com/)(Mac OS), [Git bash](https://git-scm.com/downloads) (Windows)
- A [Cloudinary](https://cloudinary.com/signup) account

## Creating a Cloudinary account

Cloudinary is a cloud-based image and video management platform used by engineering teams and developers alike to manage media assets(images, videos) in their applications. Before we proceed, take a minute to create your Cloudinary account [here](https://cloudinary.com/signup) if you do not already have one. We will be using Cloudinary to store and retrieve our uploaded images.

[![LogRocket Free Trial Banner](https://i0.wp.com/blog.logrocket.com/wp-content/uploads/2017/03/f760c-1gpjapknnuyhu8esa3z0jga.png?resize=1200%2C280&ssl=1)](https://logrocket.com/signup/)

## Setting up React

In this project, we will set up a small React application to demonstrate how to handle images in React with Cloudinary.

Run this command below to create your React app in seconds using the terminal of your choice:

```jsx
npx create-react-app react-image-app
```

When this is done you should get a similar result like the one below in your terminal: ![Result from terminal window on a successful app creation](https://i0.wp.com/blog.logrocket.com/wp-content/uploads/2020/05/resultfromterminalwindow.png?resize=730%2C456&ssl=1) Run this command to change the current directory to your newly created React app and start it up:

```jsx
cd react-image-app && npm start
```

And you should be greeted with this screen on your default browser:

![home page](https://i0.wp.com/blog.logrocket.com/wp-content/uploads/2020/05/homepage.png?resize=730%2C436&ssl=1)

Now that we have our React app up and running, let us edit it to contain an input field and a place to display images.

Open up your preferred editor and replace the content of `/src/App.js` with this:

```jsx
import React from 'react';
import './App.css';

class App extends React.Component{
  state = {
    imageUrl: null,
    imageAlt: null,
  }

  render() {
    const { imageUrl, imageAlt } = this.state;

    return (
      <main className="App">
        <section className="left-side">
          <form>
            <div className="form-group">
              <input type="file"/>
            </div>

            <button type="button" className="btn" onClick={this.handleImageUpload}>Submit</button>
            <button type="button" className="btn widget-btn">Upload Via Widget</button>
          </form>
        </section>
        <section className="right-side">
          <p>The resulting image will be displayed here</p>
          {imageUrl && (
            <img src={imageUrl} alt={imageAlt} className="displayed-image"/>
          )}
        </section>
      </main>
    );
  }
}

export default App;
```

This block of code above returns a class component in React. This component renders an interface where we can upload images from.

On line 5 we set the URL and the alternate message for the image to be `null` because we do not have any default values for those image properties. On line 26 we write a conditional rendering using the `&&` operator. This is similar to an inline if else statement, except here if the expression resolved to false, nothing is being rendered to the interface. In this case, if there is no URL for the image, the image tag will not be rendered.

From lines 15-24 we have the left-hand side of the interface with an input field with the `file` type, this is used for uploading file types from your device such as Pdf’s, images, audio, video, etc. We also defined an `onClick` function for the button called `handleImageUpload` which currently does not do anything.

The result currently looks like this:

![](https://i1.wp.com/blog.logrocket.com/wp-content/uploads/2020/05/onclickresult.png?resize=730%2C433&ssl=1)

This doesn’t currently look aesthetically appealing, so let’s add some styling with CSS. Go ahead and replace the content of `/src/App.css` with this:

```jsx
.App {
  text-align: center;
  max-width: 100vw;
  min-height: 100vh;
  max-height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
}

.App .left-side {
  display: flex;
  justify-content: center;
  align-items: center;
  border-right: .5px solid grey;
}

.App .right-side {
  border-left: .5px solid grey;
}

.App .left-side,
.App .right-side {
  height: 300px;
  width: 100%;
}

.App .left-side form {
  height: fit-content;
  background: white;
  border: 1px solid grey;
  border-radius: 4px;
  width: 300px;
  padding: 40px 10px;
}

.App .left-side form input {
  margin: 0 0 30px;
  width: 200px;
}

.App .left-side form .btn {
  height: 40px;
  width: 200px;
  background: white;
  border: 1px solid grey;
  cursor: pointer;
  border-radius: 4px;
}

.App .left-side form .btn:hover {
  color: white;
  background: grey;
}

.App .left-side form .btn:focus {
  box-shadow: none;
  outline: none;
}

.App .left-side form .btn.widget-btn {
  margin-top: 15px;
  background: #800080;
  border: 1px solid #800080;
  color: #FFFFFF;
}

.App .left-side form .btn.widget-btn:hover {
  margin-top: 15px;
  background: #4B0082;
  border: 1px solid #4B0082;
  color: #FFFFFF;
}

.App .right-side .displayed-image {
  height: 300px;
  width: 300px;
}
```

Here we use CSS [Flexbox](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Flexible_Box_Layout/Basic_Concepts_of_Flexbox), to align out elements on the screen properly. We also add background colors and hover effects to our button. Now your application on [`http://localhost:3000/`](http://localhost:3000/) should look like this:

![Visual Output of setup](https://i2.wp.com/blog.logrocket.com/wp-content/uploads/2020/05/Visual-Output-of-setup.png?resize=730%2C434&ssl=1)

Now that we have our interface setup, let us talk about how we would handle images via Cloudinary.

## Handling images via Cloudinary endpoint

In this method, we will upload images to Cloudinary by sending a POST request to a Cloudinary endpoint. This will upload the image and return a response object to us. Let’s take a look.

First, we will write some JavaScript code to get the selected image from our device. If you take a look at your `/src/App.js` on line 17 you will notice that we called a function named `handleImageUpload()`. This is the function that will handle the image upload to Cloudinary via an endpoint.

**STEP 1** : Add this block of code just before the return statement in the App function:

```jsx
handleImageUpload = () => {
  const { files } = document.querySelector('input[type="file"]')
  console.log('Image file', files[0])
}
```

This function queries the document to get the first input element with the type of file, then it de-structures the files array from the resulting object, then finally logs the first element of the array in the result to the console. This code could be expanded to look more like this:

```jsx
handleImageUpload = () => {
  // get the first input element with the type of file,
  const imageFile = document.querySelector('input[type="file"]')
  // destructure the files array from the resulting object
  const files = imageFile.files
  // log the result to the console
  console.log('Image file', files[0])
}
```

[Destructuring](https://exploringjs.com/es6/ch_destructuring.html) is a convenient way of extracting multiple values from data stored in (possibly nested) objects and arrays.

If we head over to our browser and choose and image file then click on the upload button we should have something similar to this:

![upload button in browser](https://i0.wp.com/blog.logrocket.com/wp-content/uploads/2020/05/uploadbutton.png?resize=730%2C434&ssl=1)

We can see the `file` object logged to our console. This object contains various data such as name of the file, size of the file, type of file, etc.

**STEP 2** : We are going to send a post request to a Cloudinary endpoint with the file object we got from the function above.

The base Cloudinary API endpoint looks like this:

[`https://api.Cloudinary.com/v1_1/:cloud_name/:action`](https://api.cloudinary.com/v1_1/:cloud_name/:action)

`:cloud_name` can be gotten from your Cloudinary dashboard:

![](https://i2.wp.com/blog.logrocket.com/wp-content/uploads/2020/05/cloudinary.png?resize=1282%2C662&ssl=1)

While the `:action` parameter in the URL represents whatever action you want to perform example `/image/upload` for uploading an image. A sample API URL would look like this:

[`https://api.Cloudinary.com/v1_1/john1234/image/upload`](https://api.cloudinary.com/v1_1/john1234/image/upload)

Where `:cloud_name` is `john1234` and `:action` is `/image/upload`.

The last thing we need to set for now is an upload preset. An upload presets allow you to define the default behavior for your uploads. You can add an upload preset by navigating to settings then uploads in your Cloudinary dashboard. When you are done you should have something like this:

![upload preset](https://i0.wp.com/blog.logrocket.com/wp-content/uploads/2020/05/uploadpreset.png?resize=730%2C434&ssl=1)

Now it is time to write the code that sends the POST request to our endpoint with all the necessary data.

Replace the code in your `handleImageUpload()` function with this:

```jsx
const { files } = document.querySelector('input[type="file"]')
const formData = new FormData();
formData.append('file', files[0]);
// replace this with your upload preset name
formData.append('upload_preset', 'qv5rfbwg');
const options = {
  method: 'POST',
  body: formData,
};

// replace cloudname with your Cloudinary cloud_name
return fetch('https://api.Cloudinary.com/v1_1/:cloud_name/image/upload', options)
  .then(res => res.json())
  .then(res => console.log(res))
  .catch(err => console.log(err));
```

Replace the cloud_name on line 12 with your own Cloudinary cloud_name. This can be gotten from your Cloudinary dashboard:

![cloudinary dashboard](https://i0.wp.com/blog.logrocket.com/wp-content/uploads/2020/05/cloudinarydashboard.png?resize=1282%2C662&ssl=1)

Replace the upload preset you had set at the end of step 2. Replace the dummy preset on line 4 above with your upload preset name. This can be found in the uploads section of the settings in your Cloudinary dashboard, to get there click on the gear icon on the top right section of your Cloudinary dashboard:

![](https://i2.wp.com/blog.logrocket.com/wp-content/uploads/2020/05/step2.png?resize=730%2C109&ssl=1)

Then click on the `Upload` tab on the settings page:

![upload tab on settings page](https://i2.wp.com/blog.logrocket.com/wp-content/uploads/2020/05/uploadtab.png?resize=730%2C255&ssl=1)

Scroll down to the bottom of the page to where you have upload presets and you should see your upload preset or an option to add a new one if you do not have any.

We can head over to our React app in the browser and upload an image, we should see something like this:

![upload result](https://i2.wp.com/blog.logrocket.com/wp-content/uploads/2020/05/uploadresult.png?resize=730%2C434&ssl=1)

Here we can see that our image has successfully uploaded and a response has been returned to us. To confirm that the image has been uploaded you can go ahead and copy the value of `secure_url` and paste it in the address box of a new tab and you will see your uploaded image.

**STEP 3** : Here we will display the result of our upload on the right-hand side of our React app. We will do this by replacing the code that logs the result of the uploaded image to the console with this code block:

```jsx
// Replace
.then(res => console.log(res))

// with this
.then(res => {
    this.setState({
      imageUrl: res.secure_url,
      imageAlt: `An image of ${res.original_filename}`
    })
  })
```

Upload another image and your result should be something similar to this:  
![second image uploaded](https://i2.wp.com/blog.logrocket.com/wp-content/uploads/2020/05/upload2.png?resize=730%2C434&ssl=1)To confirm this you can go to your Cloudinary media library from your Cloudinary dashboard and see all your uploads.

## Handling images via Cloudinary widget

In this method, we will invoke a Cloudinary widget called _Upload Widget_ and let it handle the image for us. With this Cloudinary widget we can pretty much upload images from various places, such as Dropbox, Facebook, Instagram, we can even take pictures with it. Sounds Interesting? Let’s get into it.

STEP 1: Here we will include the widget’s remote JavaScript file in our in index HTML file located in `public/index.html`. We will include this file using the `script` tag just above the closing `body` tag:

```jsx
<script
  src="https://widget.Cloudinary.com/v2.0/global/all.js"
  type="text/javascript"
></script>
```

**STEP 2** : We will create the widget and open it up when clicked. These two actions will be wrapped in a function.

```jsx
// ...
openWidget = () => {
  // create the widget
  window.Cloudinary.createUploadWidget(
    {
      cloudName: 'john',
      uploadPreset: 'qv5rfbwg',
    },
    (error, result) => {
      this.setState({
        imageUrl: result.info.secure_url,
        imageAlt: `An image of ${result.info.original_filename}`
      })
    },
  ).open(); // open up the widget after creation
};

//...
```

This block of code should be placed above the render function. We are also using the same information from the previous method such as `cloud_name` and `uploadPreset`. The function that opens up the widget is appended to the `createUploadWidget()`. Alternatively, you could write this function like this:

```jsx
// ...
openWidget = () => {
  // create the widget
  const widget = window.Cloudinary.createUploadWidget(
    {
      cloudName: 'john',
      uploadPreset: 'qv5rfbwg',
    },
    (error, result) => {
      if (result.event === 'success') {
        this.setState({
          imageUrl: result.info.secure_url,
          imageAlt: `An image of ${result.info.original_filename}`
        })
      }
    },
  );
  widget.open(); // open up the widget after creation
};

//...
```

Either way, the widget will be created and opened up at once after creation.

We will just call this function when the purple button is clicked. Update your button with the class of `widget-btn` code to look like this:

```jsx
<button type="button" className="btn widget-btn" onClick={this.openWidget}>Upload Via Widget</button>
```

Now when you click the widget button on your React app in the browser, you should see something similar to this:

![An open Cloudinary upload widget](https://i2.wp.com/blog.logrocket.com/wp-content/uploads/2020/05/An-open-Cloudinary-upload-widget.png?resize=730%2C434&ssl=1)

The beauty of this is that you can customize your widget to suit your needs. To do that go ahead and visit this [page](https://cloudinary.com/documentation/upload_widget#look_and_feel_customization) for more details on the widget customization.

You can go ahead and upload your image and watch it display on the right-hand side of your React application:

![final display](https://i0.wp.com/blog.logrocket.com/wp-content/uploads/2020/05/finaldisplay.png?resize=730%2C434&ssl=1)

## Conclusion

Cloudinary makes it very easy for us to handle our images, especially with the Cloudinary widget. The code for this project can also be found in this [repository](https://github.com/NedyUdombat/react-image-app) for your reference.

* * * 
## Full visibility into production React apps 

Debugging React applications can be difficult, especially when users experience issues that are difficult to reproduce. If you’re interested in monitoring and tracking Redux state, automatically surfacing JavaScript errors, and tracking slow network requests and component load time, [try LogRocket.](https://www2.logrocket.com/react-performance-monitoring)

![Alt Text](https://thepracticaldev.s3.amazonaws.com/i/eq752g8qhbffxt3hp9t4.png)

[LogRocket](https://www2.logrocket.com/react-performance-monitoring) is like a DVR for web apps, recording literally everything that happens on your React app. Instead of guessing why problems happen, you can aggregate and report on what state your application was in when an issue occurred. LogRocket also monitors your app's performance, reporting with metrics like client CPU load, client memory usage, and more.

The LogRocket Redux middleware package adds an extra layer of visibility into your user sessions. LogRocket logs all actions and state from your Redux stores.

Modernize how you debug your React apps — [start monitoring for free.](https://www2.logrocket.com/react-performance-monitoring)
* * *

The post [Handling images with Cloudinary in React](https://blog.logrocket.com/handling-images-with-cloudinary-in-react/) appeared first on [LogRocket Blog](https://blog.logrocket.com).