As my readers know, I've been updating some of my earlier Vue.js examples to demonstrate how they would work with . Normally I post these "conversions" when I see one of the Vue posts pop up in my stats. Today I noticed this entry was "trending" - . I thought it would be a great candidate for showing an Alpine version. Let's take a look. Alpine.js Vue Quick Shot - Downloading Data as a File While I won't repeat everything from the previous post, I'll quickly cover how it worked. First, it makes use of the attribute of the anchor tag. This will take a normal link operation and instead ask the browser to download the resource at the URL. To do this with client-side data, you can create an anchor tag with , set it to point to your data, and then emulate a event. I used this a few days ago in an Eleventy article: . download createElement click Adding Download Support in an Eleventy Site In the original article, I first demonstrated downloading a JSON file. But as most humans don't speak JSON, I then used to convert it to CSV. I'm going to follow the same flow for this update. Papa Parse First Version - Downloading JSON Data For the first version, we're going to look at a tabular set of cats. I will not make you scroll past the gratuitous picture of a cat on a table. Heh, I lie: Ok, so our data: "cats":[ {"name":"Alese", "gender":"female", "age": 10}, {"name":"Sammy", "gender":"male", "age": 12}, {"name":"Luna", "gender":"female", "age": 8}, {"name":"Cracker", "gender":"male", "age": 7}, {"name":"Pig", "gender":"female", "age": 6} ] The application begins by simply rendering this into a table. (Not a sortable or paginated one, but check out my other posts for examples of that.) I started off with this HTML: Alpine.js <div x-data="app"> <table> <thead> <tr> <th>Name</th> <th>Gender</th> <th>Age</th> </tr> </thead> <template x-for="cat in cats"> <tr> <td x-text="cat.name"></td> <td x-text="cat.gender"></td> <td x-text="cat.age"></td> </tr> </template> </table> </div> Alpine is used to loop over the array. Here's the initial JavaScript: cats document.addEventListener('alpine:init', () => { Alpine.data('app', () => ({ cats:[ {name:"Alese", gender:"female", age: 10}, {name:"Sammy", gender:"male", age: 12}, {name:"Luna", gender:"female", age: 8}, {name:"Cracker", gender:"male", age: 7}, {name:"Pig", gender:"female", age: 6} ] })) }); Now I'm going to add a download button that will trigger the download process: <button @click="download">Download</button> I then added my handler. This code is a bit simpler than the previous version which added to anchor to the DOM, invisibly, and then clicked. download() { let text = JSON.stringify(this.cats); let filename = 'cats.json'; let element = document.createElement('a'); element.setAttribute('href', 'data:application/json;charset=utf-8,' + encodeURIComponent(text)); element.setAttribute('download', filename); element.click(); } If you read my previous article involving , the biggest difference here is creating the data URL string that has the original data encoded into a string. You can test this version yourself here: Eleventy and downloads https://codepen.io/cfjedimaster/pen/YzjzaGz?embedable=true Second Version - Downloading CSV For the next version, we just need to convert the JSON data to CSV. Once again I'll use as it makes this trivial. Instead of Papa Parse let text = JSON.stringify(this.cats); We can use: let text = Papa.unparse(this.cats); I then made two more changes. First, the filename: let filename = 'cats.csv'; And then the mime-type: element.setAttribute('href', 'data:text/csv;charset=utf-8,' + encodeURIComponent(text)); That's literally the entire change. Now when clicking download you get a CSV that can be opened in Excel. My previous post had a screenshot of that but as this was before you could use Dark mode in Office, I figured I'd update it with a new one: Here's the entire example: https://codepen.io/cfjedimaster/pen/yLqLKoj?embedable=true Also published . here