How can I download image in React?
Asked Answered
S

6

16

I want to try to download an image by clicking on a button, but when I click on the button, it is not downloading the image, but it is directly opening the image. But I want to download the image, so how can I download the image in React?

<a
  href="https://timesofindia.indiatimes.com/thumb/msid-70238371,imgsize-89579,width-400,resizemode-4/70238371.jpg"
  download
>
  <i className="fa fa-download" />
</a>
Selfevident answered 16/7, 2019 at 11:58 Comment(3)
The download attribute only works for same-origin URLs - you can't use it to download a file from another site.Tullis
so what is solution for download when different-origin URLs?Selfevident
You can refer the URL #65382223Tetragon
H
25

I came across this SO question trying to figure out how to download a PNG image and found that Shubham Verma's answer didn't quite do it for me as the downloaded file couldn't be opened. I needed to use arraybuffer to convert the image.

Here's the code that worked.

function App() {
  const download = e => {
    console.log(e.target.href);
    fetch(e.target.href, {
      method: "GET",
      headers: {}
    })
      .then(response => {
        response.arrayBuffer().then(function(buffer) {
          const url = window.URL.createObjectURL(new Blob([buffer]));
          const link = document.createElement("a");
          link.href = url;
          link.setAttribute("download", "image.png"); //or any other extension
          document.body.appendChild(link);
          link.click();
        });
      })
      .catch(err => {
        console.log(err);
      });
  };
  return (
    <div className="App">
      <a
        href="https://upload.wikimedia.org/wikipedia/en/6/6b/Hello_Web_Series_%28Wordmark%29_Logo.png"
        download
        onClick={e => download(e)}
      >
        <i className="fa fa-download" />
        download
      </a>
    </div>
  );
}

Codesandbox: https://codesandbox.io/s/dreamy-gould-h1l72

P.S.: The download approach was taken from the following answer, but I used plain fetch instead of Axios. Download binary file with Axios

Hague answered 5/4, 2020 at 13:18 Comment(2)
I'm using Chrome latest version (as of 16 Feb 2024) and this approach does no longer work (you can test in the codesandbox provided). It opens the image url in the same tab.Alikee
add e.preventDefault(); to stop the image from also opening in a new windowBeriosova
C
18

Install file-saver package:

npm i file-saver

Your React component:

  import { saveAs } from 'file-saver'

  const Index = () => {
    const downloadImage = () => {
      saveAs('image_url', 'image.jpg') // Put your image URL here.
    }

    return <Button onClick={downloadImage}>Download!</Button>
  }
Carnivore answered 16/7, 2021 at 0:29 Comment(2)
can we use this library to save images in phone gallery?Automotive
This opens the image in a new tab in Firefox, it doesn't download it.Bethesda
D
8

You can do something like this:

function App() {
  const download = () => {
    var element = document.createElement("a");
    var file = new Blob(
      [
        "https://timesofindia.indiatimes.com/thumb/msid-70238371,imgsize-89579,width-400,resizemode-4/70238371.jpg"
      ],
      { type: "image/*" }
    );
    element.href = URL.createObjectURL(file);
    element.download = "image.jpg";
    element.click();
  };
  return (
    <div className="App">
      <a
        href="https://timesofindia.indiatimes.com/thumb/msid-70238371,imgsize-89579,width-400,resizemode-4/70238371.jpg"
        download
        onClick={() => download()}
      >
        <i className="fa fa-download" />
        download
      </a>
    </div>
  );
}

Here is a working URL: https://codesandbox.io/s/clever-noether-3nu2p?fontsize=14

Note: More things can be done. I have just created this for demo purposes.

Denton answered 16/7, 2019 at 12:57 Comment(2)
its download but image not able to openSelfevident
It doesnt work anymore ..also checked on your provided linkHypermetropia
R
3

Here is an example to download an image with a URL and dynamic name.

const download = async() => {
    const originalImage = "https://cdn1.iconfinder.com/data/icons/ninja-things-1/1772/ninja-simple-512.png";
    const image = await fetch(originalImage);

    // Split image name
    const nameSplit = originalImage.split("/");
    const  duplicateName = nameSplit.pop();

    const imageBlog = await image.blob()
    const imageURL = URL.createObjectURL(imageBlog)
    const link = document.createElement('a')
    link.href = imageURL;
    link.download = "" + duplicateName + "";
    document.body.appendChild(link)
    link.click()
    document.body.removeChild(link)
};
Radiobiology answered 9/11, 2021 at 13:10 Comment(0)
P
0

The file-saver package helps us to save files on the client-side for web applications.

  • Installation:

    npm i file-saver
    
  • Syntax:

    FileSaver.saveAs("https://codemaker2015.github.io/image", "image.jpg");
    
  • Usage:

    import { saveAs } from 'file-saver'
    
    const Main = () => {
        const downloadImage = () => {
            saveAs('image_url', 'image.jpg') // Put your image URL here.
        }
    
        return <Button onClick={downloadImage}>Download</Button>
    }
    

For more, see its npm page.

Pitre answered 18/11, 2022 at 3:29 Comment(0)
O
-1
const Download = () => {
  const [downloadURL, setDownloadURL] = useState("");

  const download = async () => {
    const result = await fetch(fetchURLHere, {
      method: "GET",
      headers: {},
    });
    const blob = await result.blob();
    const url = URL.createObjectURL(blob);
    setDownloadURL(url);
  };

  const handleDownload = async (e) => {
    try {
      await download();
      // Call this method when you've finished using an object URL to let the browser know not to keep the reference to the file any longer.
      URL.revokeObjectURL(downloadURL);
    } catch (error) {
      console.error(error);
    }
  };

  return (
    <button onClick={handleDownload} type="button" className="">
      <a href={downloadURL} download={setNameForFile}>
        Download Image
      </a>
    </button>
  );
};
Obidiah answered 22/1, 2023 at 21:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.