File download functionality
Clear and concise description of the problem
Scenario:
- User clicks a button to download a file from server
- this initiates api request to the server that returns file content
- now we need to let browser download that file to the user's computer
The last step usually requires to create a fake <a/> tag with the file content in href and then clicking it, then removing. Something like below:
const download = (data, name, type) => {
const url = window.URL.createObjectURL(new Blob([data], { type }));
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', name);
document.body.appendChild(link);
link.click();
setTimeout(() => {
document.body.removeChild(link);
window.URL.revokeObjectURL(url);
}, 200);
};
Suggested solution
In module Browser we could provide a method like useDownloadFileFromContent that would do something like below (by no means this is a production ready code but just a reference to show the idea):
const download = (data, name, type) => {
const url = window.URL.createObjectURL(new Blob([data], { type }));
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', name);
document.body.appendChild(link);
link.click();
setTimeout(() => {
document.body.removeChild(link);
window.URL.revokeObjectURL(url);
}, 200);
};
Alternative
Manually do all the steps described above
Additional context
No response
Validations
- [X] Follow our Code of Conduct
- [X] Read the Contributing Guidelines.
- [X] Read the docs.
- [X] Check that there isn't already an issue that request the same feature to avoid creating a duplicate.
Using JavaScript to trigger downloads can indeed be a bit more involved than using simple anchor tags, especially considering scenarios where permission checks or additional tasks are required. In the context of the example provided, it might seem more intuitive to utilize anchor tags directly.
In Vue applications, handling downloads can often be streamlined by incorporating authentication checks and enabling download functionality dynamically. This aligns well with Vue's reactive nature.
While the example showcases plain JavaScript, integrating similar functionality into a Vue application is indeed feasible and straightforward. Therefore, it's reasonable to ponder whether such a specific approach, lacking in versatility, would be included in VueUse.
As for using window.open(), it could serve as a viable workaround to achieve similar functionality by opening the file URL in a new tab for download. It's worth considering such alternatives for achieving the desired outcome.
There are other scenarios too actually, like when the file that needs to be downloaded is created on client side.
I.e. user clicks a button -> file is generated on client -> then downloaded locally.
For example a snapshot when jpeg is created programmatically or when generating a pdf or relatively small csv file to download etc. etc.
There might be other scenarios too, those are just the ones I've faced and saw people are dealing with.
Of course one can argue about simplicity and versatility, but that's guys for you to decide.