There are multiple ways available to download a file in JavaScript. You can either use the anchor's download attribute or programmatically create an object URL in JavaScript.

The download attribute

The download attribute was added to the anchor element in HTML 5. It informs the browser to download the requested URL instead of navigating to it.

<a href="file.pdf" download>Download PDF</a>

You can also specify an optional value for the download attribute to be used as a file name once it is downloaded. If the value is not provided, the original filename is used.

<a href="file.pdf" download="resume.pdf">Download PDF</a>

As you can see above, the download attribute is the easiest way to download a file on the browser. You do not even need JavaScript for this since it is part of HTML DOM. However, the download attribute only works in modern browsers. Internet Explorer does not support it.

Trigger the click event

The idea is to programmatically create an anchor link, and then trigger the click event. This method is especially helpful for dynamically generated file URLs.

const download = (path, filename) => {
    // Create a new link
    const anchor = document.createElement('a');
    anchor.href = path;
    anchor.download = filename;

    // Append to the DOM
    document.body.appendChild(anchor);

    // Trigger `click` event
    anchor.click();

    // Remove element from DOM
    document.body.removeChild(anchor);
}; 

// Example download
download('atta-resume.pdf', 'resume.pdf');

The above example code does the following:

  • creates an anchor element (<a>)
  • set its target URL and download attribute value (if any)
  • append it to the body
  • trigger anchor's click event to start download
  • and finally remove the anchor tag from the body

Blobs and object URLs

Sometimes, you may want to save programmatically generated data as a file using JavaScript. That's where blobs and object URLs are useful.

A Blob object is a file-like object used to represent raw immutable data. Blob objects contain information about the type and size of data they store, making them very useful for storing dynamic contents in the browser.

Let us say that you want to save the JSON response returned by a REST API as a file inside the browser:

fetch('https://reqres.in/api/users')
    .then(res => res.json())
    .then(json => {
        // TODO: Convert JSON object to blob
    })
    .catch(err => console.error(err));

To create a blob object from the JSON data, you first need to convert it into a JSON string and then create an instance of the Blob by using its constructor:

// Convert JSON to string
const data = JSON.stringify(json);

// Create a Blob object
const blob = new Blob([data], { type: 'application/json' });

To transform raw blob data into an object URL, you can use the URL.createObjectURL() method. This method is helpful to create an object URL that represents a blob or a file.

Here is what it looks like creating an object URL:

const url = URL.createObjectURL(blob);

Now we have an object URL, we can simply call the download() method defined above to save the JSON response as a file:

download(url, 'users.json');

By default, whenever an object URL is created, it remains in the DOM for the lifetime of the document. The browser will release all object URLs when the document is closed or reloaded.

However, it is a good practice to release object URLs whenever they are no longer required to improve performance and minimize memory usage. To release URL objects, you can use the URL.revokeObjectURL() method:

URL.revokeObjectURL(url);

Here is what our complete example code looks like:

fetch('https://reqres.in/api/users')
    .then(res => res.json())
    .then(json => {
        // Convert JSON to string
        const data = JSON.stringify(json);

        // Create a Blob object
        const blob = new Blob([data], { type: 'application/json' });

        // Create an object URL
        const url = URL.createObjectURL(blob);

        // Download file
        download(url, 'users.json');

        // Release the object URL
        URL.revokeObjectURL(url);
    })
    .catch(err => console.error(err));

✌️ Like this article? Follow me on Twitter and LinkedIn. You can also subscribe to RSS Feed.