Skip to content

Create a Responsive React Image Component

Images are an important part of the web, so delivering the right image for the right device at the right time while maintaining optimized quality is very important.

In this article, we’ll go over a few techniques using Cloudinary-React SDK v2 and JavaScript SDK v2 to apply transformations to our images.

Here’s a link to the demo on CodeSandbox.

If you don’t have a Cloudinary account yet, you can sign up for a free account. Log in after creating your account, and on your dashboard page, you should see all your credentials (cloud name, etc.) We’re only interested in the cloud name since that’s what we’ll need in our React application.

Open your terminal and run the following command to bootstrap a React app with CRA (create-react-app) template in a folder called my-project.

    npx create-react-app my-project

The next step is to install the dependencies that we’ll need in this project. Run the following command to install them.

    npm install @cloudinary/url-gen @cloudinary/react --save
Code language: CSS (css)

We’ll install the Cloudinary SDKs for our React application. The @Cloudinary/url-gen package is used to configure Cloudinary, create delivery URLs for our images, and apply transformations. The transformed images will be passed as an input to the component provided by the @cloudinary/react package, which will render the media on our site.

Cloudinary provides us with different methods to apply transformations to our assets. We’ll use the URL of a remote image on the web.

Open your App.js file and add the following to it.

    import { Cloudinary } from "@cloudinary/url-gen";
    import { AdvancedImage } from "@cloudinary/react";
    import { fill } from "@cloudinary/url-gen/actions/resize";
    import { Effect } from "@cloudinary/url-gen/actions/effect";
    import { byRadius } from "@cloudinary/url-gen/actions/roundCorners";
    import { byAngle } from "@cloudinary/url-gen/actions/rotate";
    const cld = new Cloudinary({
      cloud: {
        cloudName: "ifeomaimoh"
      }
    });
    const App = () => {
      const file =
        "https://images.pexels.com/photos/2246476/pexels-photo-2246476.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940";
      let image = cld.image(file);
      image = image.setDeliveryType("fetch");
      image = image
        .effect(Effect.sepia())
        .resize(fill().height(500).width(490))
        .roundCorners(byRadius().radius(40))
        .rotate(byAngle(20));
    
      // This gives the full delivery URL of the tranformations applied above.
      console.log({ url: image.toURL() });
    
      return (
        <div style={{ padding: "5rem" }}>
          <h1 style={{ marginBottom: "50rem" }}>scroll to lazy load </h1>
          <AdvancedImage cldImg={image} />
        </div>
      );
    };
    export default App;
Code language: JavaScript (javascript)

In the code snippet above, we’ll import the Cloudinary class, the AdvancedImage React component, and some qualifiers that we’ll use to build and transform our image URL. We’ll start by configuring our Cloudinary instance with our cloud name. Inside the App component, we’ll define and store the URL of a remote image in a variable called file, then instantiate a CloudinaryImage object and pass the variable to it.

We’ll also specify how we want our image to be delivered. We’ll set the delivery type to fetch for our remote image by calling the setDeliveryType method. We’ll also transform our image using the transformation actions and qualifiers on the CloudinaryImage object. We’ll apply the sepia effect to the image, resize it, add rounded corners, and rotate it.

https://res.cloudinary.com/<cloud_name>/image/<delivery type>/<transformations>/<file>

From the format above, we can see where the transformation parameters live.

The order in which you write transformations is important to get the desired effects.

Finally, we’ll pass the transformed image object to the cldImg attribute in the AdvancedImage component, which renders the image on our site. Open your terminal and start your application to see the transformed image.

Under the hood, the AdvancedImage component will fetch the image from the webserver where it’s located and then apply the transformations we specified.

There are plugins provided by the Cloudinary React library that help optimize the way you render media on your site. Let’s check out three of them, but let’s first look at the quality transformation parameter.

Quality Optimization The quality transformation parameter enables us to choose the quality compression level for our images, with values ranging from 1 to 100. The lower the quality value, the more the file is compressed to smaller file size.

Let’s update our App.js file to include the following:

     image = image
        ...
        ...
        .rotate(byAngle(20))
        .quality ('q_40');
Code language: JavaScript (javascript)

We’ll add the quality transformation parameter q_40 and specify that we want an image quality of 40. The result is a compressed image with small size and good quality. For most images, specifying an optimal value is difficult If we seek to optimize our images while maintaining quality. Cloudinary also provides us with a quality transformation parameter auto, which delivers an image with an automatically determined level of quality. You can also set the default image quality level in the Upload Settings for your account.

Below is the result of applying different quality values.

Other variants of the auto parameter include q_auto:low, q:auto:best, etc., each with different compression levels. See here for more options.

Lazy Loading Images This ensures that images are delayed and loaded only when they’re visible in the viewport. Add the following plugins to the list of your imports.

    import {Cloudinary} from '@cloudinary/url-gen';
    import {
      AdvancedImage,
      lazyload,
      responsive,
      placeholder,
    } from '@cloudinary/react';
Code language: JavaScript (javascript)

Let’s now update our App component to include the plugins we imported.

    const App = () =>{
    const image = ...
    ....
      return (
        <div style={{paddingBottom: '30rem'}}>
          <h1>scroll to lazy load </h1>
          <p style={{marginBottom: '50rem'}} />
          <AdvancedImage
            cldImg={image}
            plugins={[lazyload ('0', 1), placeholder ('blur')]}
          />
        </div>
      );
    }
Code language: JavaScript (javascript)

In the code snippet above, we’ll use the lazyload and placeholder plugin in the AdvancedImage component. The lazyload plugin uses the intersection observer API under the hood to detect if a user scrolls near the image or iframe before loading it. We’re saying we want our image loaded when it is 100% visible on the page. Lazy loading images helps conserve bandwidth for images that are not seen and reduce the time needed to load a page.

We’ll use the placeholder plugin to render a fallback image while the image is being loaded. The placeholder image loads quickly, and your page content won’t jump around. Because we’ve specified “blur” as our placeholder option, we’ll get a blurred version of the target image while waiting for the full quality image to be downloaded.

Responsive Images Initially, we resized our image using the resize qualifier. Although this works, the dimension of the image will remain static as the viewport size changes. Cloudinary React library provides the responsive() plugin that we can use to resize our image based on the viewport size automatically.

First, we’ll need to remove the resize qualifier.

    // Remove this line of code.
    .resize(fill().height(500).width(490))
Code language: JavaScript (javascript)

Let’s include the responsive plugin in our App component.

    plugins={[lazyload ('0', 1),responsive(200),placeholder ('blur')]}
Code language: JavaScript (javascript)

The order of the plugins is important to ensure that everything works correctly.

The responsive plugin function accepts either a single value (step) or an array of values. In our case, we passed in a single value – 200 pixels. Each time the viewport size increases or decreases by that value, a new image will be loaded.

Find the source code here on Github.

In this article, we explored how to use some of the advanced features of the Cloudinary-React SDK and JavaScript SDK to build and apply various transformations to our image component. You can find more information about the Cloudinary React SDK v2 and plugins here.

Want to discuss the topic of this blog? Head over to the Cloudinary Community forums or Discord and get all your questions answered!

Resources

Back to top

Featured Post