Cloudinary Blog

Building a React Image Gallery With Cloudinary

Building a React Image Gallery With Cloudinary

To start building a user interface, you might use React, a JavaScript library for building flexible and reusable components. However, you also need a supporting tool for managing digital media (images and videos). The recently announced React SDK from Cloudinary capably serves that purpose.

In brief, the Cloudinary platform enables you to seamlessly and efficiently upload, optimize, transform, store, and deliver media across viewing devices with no quality compromise. Do check out its many feature-rich, sound capabilities.

This tutorial guides you through the steps of building a React image gallery with Cloudinary’s React SDK. It’s an intuitive, straightforward process well worth learning.


Sign up for Cloudinary free today!


Installing the Prerequisites

First, install Cloudinary’s React SDK and upload widget:

1. Specify the React app’s basic properties and requirements.

Create a file with the following JSON code to specify the basic properties for the React app and configure a minimal number of its dependencies.

Copy to clipboard
{
  "name": "img-library",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "watch": "webpack -d --watch",
    "build": "webpack",
    "serve": "serve ./public"
  },
  "author": "",
  "license": "MIT",
  "devDependencies": {
    "babel-core": "^6.18.2",
    "babel-loader": "^6.2.9",
    "babel-preset-es2015": "^6.18.0",
    "babel-preset-react": "^6.16.0",
    "serve": "^1.4.0",
    "webpack": "^1.14.0"
  },
  "dependencies": {
    "axios": "^0.15.3",
    "cloudinary-react": "^1.0.1",
    "react": "^15.4.1",
    "react-dom": "^15.4.1"
  }
}

Note
Under dependencies:

  • axios is a tool for making HTTP requests, in this case for the images on the Cloudinary server.
  • cloudinary-react refers to Cloudinary's React SDK.
  • react is the React library.
  • react-dom is the React Document Object Model (DOM).

2. Install the dependencies

Install the dependencies with this npm command line:

Copy to clipboard
# Install dependencies
npm install

3. Set up Webpack.

Webpack is the build tool. Create a file with the following JavaScript code to configure the basic Webpack settings, such as the entry, output, and loaders, for running builds and compiling React apps (.jsx files).

Copy to clipboard
// ./webpack.config.js
var webpack = require('webpack');
var path = require('path');

var BUILD_DIR = path.resolve(__dirname, 'public');
var APP_DIR = path.resolve(__dirname, 'src');

var config = {
    entry: APP_DIR + '/index.jsx',
    output: {
        path: BUILD_DIR,
        filename: 'bundle.js'
    },
    module : {
        loaders : [
            {
                test : /\.jsx?/,
                include : APP_DIR,
                loader : 'babel'
            }
        ]
    }
};

module.exports = config;

4. Create two entry points.

Create the two files below. The top one, which is in JavaScript (index.jsx), generates an entry point similar to the one configured for Webpack. The bottom one, which is in HTML (index.html), creates an entry point for the browser.

Copy to clipboard
// ./src/index.jsx
import React, { Component } from 'react';
import { render } from 'react-dom';

class Main extends Component {
    render() {
        return (
           <div className="main">
               <h1>Scotchage</h1>
           </div>
        );
    }
}

render(<Main />, document.getElementById('container'));
Copy to clipboard
<!-- ./public/index.html -->
<html>
<head>
    <!--Stylesheet-->
    <link rel="stylesheet" href="style.css">
    <meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>
    <!--Container for React rendering-->
    <div id="container"></div>
    <!--Bundled file-->
    <script src="bundle.js"></script>
</body>
</html>

5. Register for a Cloudinary account.

Sign up for a free Cloudinary account. Afterwards, your credentials are displayed on your account dashboard, as in this example:

dashboard

Uploading Images

Upload your React app’s images to Cloudinary with the latter’s upload widget. Do the following:

  1. Add the upload widget to the React app’s index.html file:

    Copy to clipboard
    <!-- ./public/index.html →
    <html>
    <head>
    . . .
    </head>
    <body>
    . . .
    <!-- UPLOAD WIDGET →
    <script src="//widget.cloudinary.com/global/all.js" type="text/javascript"></script>
    <script src="bundle.js"></script>
    </body>
    </html>
  2. Create a button, attach an event to it, and upload an image on a click of the button. Here’s the JavaScript code:

    Copy to clipboard
    import React, { Component } from 'react';
    import { render } from 'react-dom';
    
    class Main extends Component {
    
    uploadWidget() {
        cloudinary.openUploadWidget({ cloud_name: 'cloud_name', upload_preset: 'preset', tags:['xmas']},
            function(error, result) {
                console.log(result);
            });
    }
    render(){
        return (
            <div className="main">
                <h1>Galleria</h1>
                <div className="upload">
                    <button onClick={this.uploadWidget.bind(this)} className="upload-button">
                        Add Image
                    </button>
                </div>
            </div>
    
        );
    }
    }
    
    render(<Main />, document.getElementById('container'));

Note

  • The uploadWidget member method is the handler invoked by the click event to upload images by calling cloudinary.openUploadWidget.
  • openUploadWidget takes as its parameters a configuration object and the upload callback handler. Be sure to specify the valid values for the cloud_name and upload_preset properties. For details, see the documentation on cloud names and upload presets.

Upload

Delivering Images with the Cloudinary React SDK

The Cloudinary React SDK comprises three major components:

  • Image: This component requests for the images defined by their IDs from the Cloudinary server and then displays the images on the browser.
  • Transformation: This component transforms the images delivered with Image.
  • CloudinaryContext: Configuring multiple images, one by one, in the Image component is tedious. Instead, you can specify the configuration for them all in this component.

Here’s a typical structure:

Copy to clipboard
<CloudinaryContext>
    <Image>
        <Transformation />
        <Transformation />
    </Image>
    <Image>
        <Transformation />
    </Image>
</CloudinaryContext>

Now request an image from the Cloudinary server and display the image with certain components through this JavaScript code:

Copy to clipboard
import React, { Component } from 'react';
import axios from 'axios';
import { CloudinaryContext, Transformation, Image } from 'cloudinary-react';
import { render } from 'react-dom';

class Main extends Component {
    constructor(props) {
        super(props);
        this.state = {
            gallery: []
        }
    }
    componentDidMount() {
        // Request for images tagged xmas       
        axios.get('https://res.cloudinary.com/christekh/image/list/xmas.json')
            .then(res => {
                console.log(res.data.resources);
                this.setState({gallery: res.data.resources});
            });
    }
    uploadWidget() {
       // . . .
    }
    render(){
        return (
            <div className="main">
                <h1>Galleria</h1>
                <div className="gallery">
                    <CloudinaryContext cloudName="cloud_name">
                        {
                            this.state.gallery.map(data => {
                                return (
                                    <div className="responsive" key={data.public_id}>
                                        <div className="img">
                                            <a target="_blank" href={`https://res.cloudinary.com/christekh/image/upload/${data.public_id}.jpg`}>
                                                <Image publicId={data.public_id}>
                                                    <Transformation
                                                        crop="scale"
                                                        width="300"
                                                        height="200"
                                                        dpr="auto"
                                                        responsive_placeholder="blank"
                                                    />
                                                </Image>
                                            </a>
                                            <div className="desc">Created at {data.created_at}</div>
                                        </div>
                                    </div>
                                )
                            })
                        }
                    </CloudinaryContext>
                    <div className="clearfix"></div>
                </div>
            </div>

        );
    }
}

render(<Main />, document.getElementById('container'));

The upload code reads like this:

Copy to clipboard
 cloudinary.openUploadWidget({ cloud_name: 'christekh', upload_preset: 'idcidr0h', tags:['xmas']},
            function(error, result) {
            . . .

Here, you’re requesting a collection of images, all tagged with xmas. That is exactly what the axios library does when the component mounts:

Copy to clipboard
axios.get('https://res.cloudinary.com/cloud_name/image/list/xmas.json')
            .then(res => {
                console.log(res.data.resources);
                this.setState({gallery: res.data.resources});
            });

axios operates on promises. Whenever a promise is resolved in the React app, a collection of images become available for UI updates through React state.

To render the images, configure the CloudinaryContext with the value of cloud_name, iterate over the gallery state, which stores the images, and displays them through the Image component. Separately, apply the transformations that you desire for the images with the Transformation component.

Note
For security, you cannot request images from the client. Instead, request them with Cloudinary’s Admin API through a backend SDK and then send the resource list to the client. See the related documentation for details.

Gallery

Updating State With New Uploads

Leverage the code below to instantly update the displayed images with the new ones uploaded by the user:

Copy to clipboard
uploadWidget() {
        let _this = this;
        cloudinary.openUploadWidget({ cloud_name: 'cloud_name', upload_preset: 'preset', tags:['xmas']},
            function(error, result) {
            // Update gallery state with newly uploaded image
                _this.setState({gallery: _this.state.gallery.concat(result)})
            });
    }

Rather than passing the image information to the Cloudinary console, the above code updates the gallery state with its list of the requested images by concatenating the uploaded result to gallery.

A React image gallery is as a handy trove for web projects. Thanks to Cloudinary’s React SDK, building it is a chore-free task.

About Cloudinary

Cloudinary provides easy-to-use, cloud-based media management solutions for the world’s top brands. With offices in the US, UK and Israel, Cloudinary has quickly become the de facto solution used by developers and marketers at major companies around the world to streamline rich media management and deliver optimal end-user experiences.

For more information, visit www.cloudinary.com or follow us on Twitter.


Referencing Related Resources

Recent Blog Posts

Create Lightweight Sites With Low-Code and No-Code Technology

Consumers expect modern websites to be mainly visual. But, the more compelling and complex the related media is, the more data is involved, compounding the site’s weight. In today’s content-craving world, delivering unoptimized media can cost you because it leads to sluggish page loads, resulting in visitors abandoning your site in search of a faster alternative. In fact, a page load that takes more than three seconds can cause as many as 40% of your visitors to bounce. Given this competitive, digital-first environment, you can’t afford to lose page views, for time is of the essence.

Read more
A Blueprint for AWS-Secured Webhook Listeners for Cloudinary

tl;dr: An AWS-secured and optimized Cloudinary webhook listener for extending the Cloudinary service

Code: Github

A webhook is a communication medium for sending notifications from one platform to another about events that occurred. In place are user-defined HTTP callbacks that are triggered by specific events. When a triggered event takes place on the source site, the webhook listens to the event, collects the data, and sends it to the URL you specified in the form of an HTTP request.

Read more
New Accessibility Features for Cloudinary’s Product Gallery Widget

Cloudinary’s Product Gallery widget, which launched in 2019, has enabled many brands to effectively and efficiently showcase their products in a sleek and captivating manner, saving countless hours of development time and accelerating release cycles. By adding Cloudinary’s Product Gallery widget with its customizable UI to their product page, retailers reap numerous benefits, often turning visitors into customers in short order.

Read more
Why Successful Businesses Engage With and Convert Audiences With Visual Media

Most business buyers prefer to research purchase options online, as do many shoppers. No wonder online retail sales in the U.S. rose by 32.4% in 2020—an impressive gain of $105 billion.

For B2B and B2C businesses, text-heavy websites are no longer adequate in attracting shoppers. Instead, engaging visual media—spin images, videos, 3D models, augmented reality—are becoming a must for conveying eye-catching details and differentiators about products or services.

Read more
Making User-Generated Content (UGC) Shoppable With Cloudinary

User-generated content (UGC) is a powerful marketing tool. Not only does video complement marketing efforts for e-commerce by enabling customers to explore products in greater detail, but UGC also adds an element of trust. As a bonus, user-generated video is an exceptional opportunity for e-businesses to attract website traffic without their marketing team having to create promotional videos from scratch. User-generated content drives conversions and brand loyalty as a direct result of authentic interaction.

Read more