How to Handle Responsive Images in React

responsive images react

React is an open-source, frontend JavaScript library for building user interfaces. Applications built in React support performance enhancement, user interface focused design, reusable components, and cross-platform support.

Due to React’s open-source initiatives, it has seen tremendous adoption in building applications that run on both web and mobile. Technologies, like Next.js, Gatsby.js, and Remix have built robust frameworks based on the React ecosystem.

Most React-based technologies are constantly improving and updating, and in response, developers are continually having to learn how to use images on various frameworks, and deal with breaking changes when upgrading project dependencies.

In this article, you will learn how to handle responsive images in React.

Some framework approaches to handling images

Most React-based frameworks provide components for rendering optimized and performant images. Let’s explore some of their syntax below:

Next.js approach: Provides an image component for rendering and optimizing images.

    <Image
      loader={myLoader}
      src="sampleImage.png"
      alt="Picture of the sample"
      width={500}
      height={500}

Gatsby approach: Provides StaticImage and GatsbyImage for rendering static and dynamic images.

    <StaticImage
      src="sampleImage.png"
      alt="Picture of the sample"
      placeholder="blurred"
      layout="fixed"
      width={500}
      height={500}

    //OR

    <GatsbyImage 
      image={sampleImage} 
      alt="Picture of the sample"
      width={500}
      height={500}

Remix approach: Uses the native img element to render images.

    <img

      src="sampleImage.png"
      alt="Picture of the sample"

While most framework-based solutions have proven to be effective in rendering and optimizing images, developers have been tasked with constantly switching context between the frameworks, keeping up-to-date on changes, and factoring in breaking changes during upgrades.

Cloudinary — learn once, implement everywhere!

Cloudinary is a visual media platform used to upload, store, manage, transform, and deliver images and videos for websites and applications. The platform also offers a vast collection of SDKs for frontend frameworks and libraries.

Cloudinary-react is a React SDK library developed to optimize and transform media assets effortlessly. Developers are independent of any framework when serving images on web applications and websites.

A Cloudinary account is needed to follow along with this tutorial. Signup is completely free and is free forever.

Sandbox

We completed this project in a CodeSandbox. Fork and run it to quickly get started on creating responsive images in React.

<CodeSandbox id="silly-davinci-s1uvmq" title="How to handle responsive images in react" />

Github link here.

“Optimise

Getting started

Create a React project by navigating to the desired directory and running the below command in a terminal:

 npx create-react-app handle_resp_img && cd handle_resp_img

The command creates a React project called ‘handle_resp_img,’ and navigates to the project directory.

* Potential breaking changes in React: due to a recent upgrade in React version (“^18.0.0”), you might need to downgrade your application to a compatible version by deleting the generated node_modules folder.

Next, modify the package.json file, as shown below:

    {
      "name": "resp_image",
      "version": "0.1.0",
      "private": true,
      "dependencies": {
        "@cloudinary/react": "^1.2.2",
        "@cloudinary/url-gen": "^1.7.0",
        "@testing-library/jest-dom": "^5.16.4",
        "@testing-library/react": "^12.1.4",
        "@testing-library/user-event": "^13.5.0",
        "react": "^17.0.0",
        "react-dom": "^17.0.0",
        "react-scripts": "5.0.0",
        "web-vitals": "^2.1.4"
      },

      "scripts": {
        "start": "react-scripts start",
        "build": "react-scripts build",
        "test": "react-scripts test",
        "eject": "react-scripts eject"
      },

      "eslintConfig": {
        "extends": [
          "react-app",

          "react-app/jest"
        ]
      },

      "browserslist": {

        "production": [
          ">0.2%",

          "not dead",
          "not op_mini all"
        ],

        "development": [
          "last 1 chrome version",
          "last 1 firefox version",
          "last 1 safari version"
        ]
      }
    }

The snippet above:

  • Line 11: changed the react version to “^17.0.0”.
  • Line 12: changed the react-dom version to “^17.0.0”.

Re-install the dependencies by running the following command:

npm install

Proceed to install the cloudinary-react dependency with:

npm i cloudinary-react

Include Cloudinary’s cloud name as an environment variable. To do this, first create a .env file in the root directory, and in this file, add the following snippet:

REACT_APP_CLOUDINARY_CLOUD_NAME=/*YOUR CLOUD NAME HERE/*

* Get the Cloudinary cloud name by logging into the Cloudinary console and viewing any of the highlighted sections shown below:

Welcome dashboard Cloudinary

Image sourcing and upload to Cloudinary

To follow along, upload the below sample image from Unsplash to handle responsive images in React.

https://images.unsplash.com/photo-1648737154547-b0dfd281c51e?ixlib=rb-1.2.1&ixid=MnwxMjA3fDF8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1470&q=80

In the Cloudinary dashboard, you can upload the image by clicking on the Media Library tab, then Upload, select the Web Address option, input the url, then clicking on the Arrow Button:

Image Upload Cloudinary

* Note there are multiple ways to upload images to Cloudinary.

After uploading the image, it will be displayed on the console with its Public ID (the unique identifier for an asset stored in Cloudinary). This ID will come in handy when creating responsive images in React.

Media Library Highlighted Image

* When you upload the image, the Public ID can be fairly long. Double click on the image to rename it.

Handling a responsive image in React

Modify the App.js file in the src folder to the following:

import './App.css';
    import { Image, Transformation, CloudinaryContext } from 'cloudinary-react';

function App() {

return (

<div className='App'>
<header>
<h1>Responsive Image</h1>
</header>
<div className='image-wrapper'>
<CloudinaryContext
cloud_name={process.env.REACT_APP_CLOUDINARY_CLOUD_NAME}
<Image publicId='photo-1648737154547-b0dfd281c51e'>
<Transformation width='400' crop='scale' />
</Image>
</CloudinaryContext>

</div>
</div>
);
}

export default App;

The above snippet:

  • Imports the required dependencies.
  • Configures CloudinaryContext as a wrapper with the cloud name. CloudinaryContext serves as a container for Cloudinary components and passes all the properties defined to the children.
  • Uses the Image component to render the uploaded image by passing in the Public ID..
  • Uses the Transformation component to transform the image as desired.With that done, we can start a development server using the below command:
    npm start

    Responsive image example

    Conclusion

    This post discussed how to handle responsive images in React. With the cloudinary-react library, developers can seamlessly optimize and deliver images across multiple React-based frameworks and libraries, without having to learn their specific approaches. Try Cloudinary out (it’s free forever!) to unleash the full potential of your digital media.

    More from Cloudinary:

    
    
QUICK TIPS
Tamas Piros
Cloudinary Logo Tamas Piros

In my experience, here are tips that can help you better handle responsive images in React:

  1. Use the srcset attribute with standard <img> tags for simple setups
    While React offers various image components and integrations, using the native HTML5 srcset attribute in <img> tags is often the easiest way to implement responsive images for small projects. This method ensures that browsers handle image selection based on device resolution without adding extra dependencies.
  2. Incorporate React hooks to dynamically load images
    Use useEffect and useState hooks to dynamically load different image resolutions based on the viewport size. For example, monitor the window.innerWidth value to update the state with the appropriate image URL whenever the window is resized.
  3. Leverage React Context API for shared image settings
    Create a context to handle shared image settings like preferred breakpoints, quality parameters, or placeholder styles across components. This approach helps centralize image-related settings, making updates and configurations easier, especially in larger applications.
  4. Use Cloudinary’s responsive breakpoints for automated variants
    When working with Cloudinary, take advantage of the responsive_breakpoints parameter to automatically generate image sizes for different screen widths. This minimizes manual image preparation and keeps your project flexible as design requirements change.
  5. Implement lazy loading with react-intersection-observer
    Use the react-intersection-observer library to implement lazy loading, where off-screen images are only fetched when they’re about to appear in the viewport. This reduces initial page load time, particularly for image-heavy pages, and is more powerful than the built-in loading="lazy" attribute.
  6. Use gatsby-image for static site generation (SSG)
    If using Gatsby, use the gatsby-image or gatsby-plugin-image package to handle responsive images. These libraries optimize images during the build process, creating multiple image sizes and lazy-loading them by default, ensuring that the resulting site is highly performant.
  7. Apply Cloudinary’s auto-quality (q_auto) and auto-format (f_auto) parameters
    When using Cloudinary, always add q_auto and f_auto to your image URLs. This combination optimizes images based on the content and the browser’s capabilities, ensuring high quality and reduced file sizes without manual adjustments.
  8. Integrate media queries directly in React components
    Use media query hooks like useMediaQuery from libraries like react-responsive to dynamically select and render different image components based on screen size. This approach provides granular control over image loading and display within React components.
  9. Combine responsive images with picture elements for art direction
    Use the <picture> element and React’s native JSX syntax to implement art-directed responsive images. This is ideal when different crops or focal points are needed based on the viewport, allowing for tailored image presentation without duplicating components.
  10. Test your images across various React environments
    Test your responsive image setups in different environments like SSR (Next.js), static site generators (Gatsby), and client-side rendered applications. Each approach might handle image loading and hydration differently, so verifying the behavior ensures consistent performance and visual fidelity across frameworks.

Implementing these tips will help you seamlessly integrate responsive images into your React projects, leveraging React’s strengths for dynamic UI updates while ensuring optimal performance and scalability.

Last updated: Oct 1, 2024