Categories
JavaScript Answers

How to Create a File in Memory for Users to Download on Client Side with JavaScript?

Spread the love

Sometimes, we may want to let users download files that aren’t stored on a server.

The data may only be available on the client-side and we want to let users download time.

In this article, we’ll look at how to create a file in memory for users to download on the client-side with JavaScript.

Setting a Tag’s href Attribute to a Base64 String

We can set an a tag’s href attribute’s value to a base64 string.

This way the data will be downloaded to the user’s computer.

For instance, we can add a text file for the user to download by writing:

<a href="data:application/octet-stream;charset=utf-16le;base64,//5mAG8AbwAgAGIAYQByAAoA">text file</a>

href is set to a base64 string.

It consists of the MIME type, which is application/octet-stream .

And the part after the double slash is the encoded text content.

Create File to Download with JavaScript

We can also create the file to download with JavaScript.

For instance, we can write the following HTML:

<button>
  download
</button>

Then we can create a function to let us download content by writing

const download = (filename, text) => {
  const element = document.createElement('a');
  element.setAttribute('href', `data:text/plain;charset=utf-8,${encodeURIComponent(text)}`);
  element.setAttribute('download', filename);
  element.style.display = 'none';
  document.body.appendChild(element);
  element.click();
  document.body.removeChild(element);
}

const button = document.querySelector('button')
button.addEventListener('click', () => {
  download('file.txt', 'foo bar')
})

In the download function, we get the filename and text parameter values.

Then in the function, we create the a element with createElement .

It’ll be invisible.

Next, we set the href attribute value of it to the content we want to the user to get, which is a base64 string with the encoded text value.

Then we set the download attribute to the filename so the file will be downloaded with the given filename.

Next, we set display style to 'none' so that it’s visible.

And then we append the a element to the body with appendChild .

To download the file, we call click to click on the invisible a element.

And finally, we call removeChild to remove the invisible a element.

Then we get the button with querySelector .

And we call addEventListener on it to add a click listener.

And in the callback, we call download with the filename and content.

Also, we can use createObjectURL to create the base64 string:

const download = (filename, text) => {
  const element = document.createElement('a');
  element.setAttribute('href', window.URL.createObjectURL(new Blob([text], {
    type: 'text/plain'
  })));
  element.setAttribute('download', filename);
  element.style.display = 'none';
  document.body.appendChild(element);
  element.click();
  document.body.removeChild(element);
}

const button = document.querySelector('button')
button.addEventListener('click', () => {
  download('file.txt', 'foo bar')
})

Conclusion

We can use base64 strings with a elements to let users download data that are only available on the client side.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *