how to download file in react js

379,828

Solution 1

Triggering browser download from the frontend is not reliable.

What you should do is, create an endpoint on a server that when called, responds with the correct response headers, thus triggering the browser download.

Frontend code can only do so much. The 'download' attribute for example, might just open the file in a new tab depending on the browser and the type of the file.

The response headers you need to look at are Content-Type and Content-Disposition. You should check this answer for a more detailed explanation on those headers.

Solution 2

This is not related to React. However, you can use the download attribute on the anchor <a> element to tell the browser to download the file.

<a href='/somefile.txt' download>Click to download</a>

This is not supported on all browsers: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a

Solution 3

If you are using React Router, use this:

<Link to="/files/myfile.pdf" target="_blank" download>Download</Link>

Where /files/myfile.pdf is inside your public folder.

Solution 4

tldr; fetch the file from the url, store it as a local Blob, inject a link element into the DOM, and click it to download the Blob

I had a PDF file that was stored in S3 behind a Cloudfront URL. I wanted the user to be able to click a button and immediately initiate a download without popping open a new tab with a PDF preview. Generally, if a file is hosted at a URL that has a different domain that the site the user is currently on, immediate downloads are blocked by many browsers for user security reasons. If you use this solution, do not initiate the file download unless a user clicks on a button to intentionally download.

In order to get by this, I needed to fetch the file from the URL getting around any CORS policies to save a local Blob that would then be the source of the downloaded file. In the code below, make sure you swap in your own fileURL, Content-Type, and FileName.

fetch('https://cors-anywhere.herokuapp.com/' + fileURL, {
    method: 'GET',
    headers: {
      'Content-Type': 'application/pdf',
    },
  })
  .then((response) => response.blob())
  .then((blob) => {
    // Create blob link to download
    const url = window.URL.createObjectURL(
      new Blob([blob]),
    );
    const link = document.createElement('a');
    link.href = url;
    link.setAttribute(
      'download',
      `FileName.pdf`,
    );

    // Append to html link element page
    document.body.appendChild(link);

    // Start download
    link.click();

    // Clean up and remove the link
    link.parentNode.removeChild(link);
  });

This solution references solutions to getting a blob from a URL and using a CORS proxy.

Update As of January 31st, 2021, the cors-anywhere demo hosted on Heroku servers will only allow limited use for testing purposes and cannot be used for production applications. You will have to host your own cors-anywhere server by following cors-anywhere or cors-server.

Solution 5

browsers are smart enough to detect the link and downloading it directly when clicking on an anchor tag without using the download attribute.

after getting your file link from the api, just use plain javascript by creating anchor tag and delete it after clicking on it dynamically immediately on the fly.

const link = document.createElement('a');
link.href = `your_link.pdf`;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
Share:
379,828
Sameer Thite
Author by

Sameer Thite

Frontend developer with 3 years of experience. 2 year experience in angularjs/angular 4 and 1 year experience in reactjs, react native.

Updated on July 29, 2022

Comments

  • Sameer Thite
    Sameer Thite almost 2 years

    I receive file url as response from api. when user clicks on download button, the file should be downloaded without opening file preview in a new tab. How to achieve this in react js?

  • Sameer Thite
    Sameer Thite almost 6 years
    Anchor tag opens image in same browser tab (preview of image) and then we need to manually save the image. I am trying to achieve automatic download on button click, without opening file preview
  • lipp
    lipp almost 6 years
    Refer to this for more details: stackoverflow.com/questions/2408146/…
  • 1020rpz
    1020rpz almost 4 years
    What you should do is, create an endpoint that when called, will provide the correct response headers, thus triggering the browser download.... What are those header and how does specifics headers can trigger browser download ? thanks
  • Rohan Kumar
    Rohan Kumar almost 4 years
    I try for zip file, the file downloads, and never unzips properly. Someone might know the reason for it? Btw, I find a workaround: stackoverflow.com/a/62855917/7622204
  • Jake
    Jake almost 4 years
    Except that browser will open a PDF, and I want it to download. Not open.
  • Jake
    Jake almost 4 years
    This is kind of a cool library. It still opened PDFs in a new tab unfortunately though. It makes opening the file on the fly a really clean process though.
  • Pankaj
    Pankaj over 3 years
    Its also working with react and node/HAPI. I have added below link.href = your_link.pdf; link.download = yourFileName; Thanks a lot.
  • Divyesh Kanzariya
    Divyesh Kanzariya over 3 years
    It will open pdf in new tab while using fileSaver
  • user
    user over 3 years
    download observes the same-origin-policy FYI
  • Santhosh
    Santhosh about 3 years
    this works well, asks for save as, which is what i was looking for
  • hoanghuychh
    hoanghuychh about 3 years
    I can't open file after download, File error : "The file (nameFile) could not be opened. It may be damaged or use a file format that Preview doesn’t recognize." Did I miss anything?
  • Admin
    Admin about 3 years
    @DivyeshKanzariya how can you resolve this question?
  • Nils Knappmeier
    Nils Knappmeier almost 3 years
    Be aware that if the page is not reloaded in your app, the blob passed to "URL.createObjectURL" will remain in memory until you call URL.revokeObjectUrl. For a long-running app, this may lead to wasted memory and perfomance issues.
  • fullStackChris
    fullStackChris over 2 years
    Update for 2021: the download property is supported in 95% of browsers: caniuse.com/download so... 🤷‍♂️
  • fatemeh kazemi
    fatemeh kazemi over 2 years
    I was able to add an epub file in the same way
  • Jackyef
    Jackyef over 2 years
    Hey, sorry for the late reply. The headers in question are Content-Type and Content-Disposition.
  • Mayank-Dolphin
    Mayank-Dolphin over 2 years
    It's working for me. Thank you for this solution.
  • Alex Aung
    Alex Aung about 2 years
    this one is good but is there a way to change label to icon?