How to create a JSON download link using HTML only
Written in May 9, 2021 - 🕒 2 min. readThis week I was working on my project Resume Builder and I wanted to be able to create a button that downloads a JSON without using JavaScript.
The only way I knew how to do that was by using URL.createObjectURL
in a blob
file, but that wouldn’t work for me, because this link would be inside a PDF file.
Then I did the first thing any millennial would do, I searched on Stack Overflow, but I couldn’t find anything… how is that even possible? Well anyway, with some trial and error I was able to do it by using Base 64.
Let’s say I want to create a download button that will download a JSON like { foo: 'bar' }
, first we need to convert it to a Base 64 string, we can do that with the native btoa
JavaScript function:
const json = { foo: 'bar' };
const jsonString = JSON.stringify(json);
const base64Json = btoa(jsonString); // eyJmb28iOiJiYXIifQ==
Ok now that I know what is the Base 64 value for the { foo: 'bar' }
object, I can create an anchor
element like the following:
<a href="data:application/json;base64,eyJmb28iOiJiYXIifQ==" download="object.json">download</a>
And that’s all. In my case, I just needed the code to be served as HTML, and since I’m using Gatsby, my actual code is a React element that will be SSR for my PDF file:
const DownloadJsonLink = ({
children,
json = {},
name = 'object.json',
}) => {
const href = useMemo(
() => {
if (typeof window !== 'undefined') {
const base64Data = btoa(unescape(encodeURIComponent(JSON.stringify(json))));
return `data:application/json;base64,${base64Data}`;
}
return '#';
},
[json]
);
return (
<a
href={href}
download={name}
target="_blank"
>
{children}
</a>
);
};
export default DownloadJsonLink;
I knew it was possible to do this to download an image, but I had never tried for other types of files.
It is amazing to still learn HTML things even after many years of experience, and I hope that someone else learns something new with this post. See you next time.
Tags:
Related posts
Post a comment
Comments
Shmu on 5/17/21
I had to create something similar for my weightlifting web application, to allow exporting your progress. When the user clicks a button, I dynamically generate this kind of anchor tag, and click it. Obviously this uses JS though. https://github.com/SamuelNorbury/norbury-lifts/blob/master/src/web/utils/export.js