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.