# How to download a file in JavaScript

By Atta Ur Rehman Shah (https://attacomsian.com/about). Published Mar 28, 2021, updated Sep 10, 2022. Topics: JavaScript, HTML.
Canonical URL: https://attacomsian.com/blog/javascript-download-file

> A quick guide to learn about different ways of downloading a file in JavaScript. 

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.

```html
<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.

```html
<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](https://attacomsian.com/blog/getting-dom-elements-javascript). 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](https://attacomsian.com/blog/javascript-create-dom-element) an anchor link, and then [trigger](https://attacomsian.com/blog/javascript-dom-trigger-built-in-and-custom-events) the `click` event. This method is especially helpful for dynamically generated file URLs.

```javascript
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](https://attacomsian.com/blog/javascript-dom-append-to-an-element) 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](https://developer.mozilla.org/en-US/docs/Web/API/Blob) 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:

```javascript
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](https://attacomsian.com/blog/json-parse-stringify) and then create an instance of the `Blob` by using its constructor:

```javascript
// 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:

```javascript
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:

```javascript
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:

```javascript
URL.revokeObjectURL(url);
```

Here is what our complete example code looks like:

```javascript
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));
```
