Making my Tracker progressively enhanced

In the old version of my tracker app, I had a terminal dependency on JavaScript. All of the data was defined inside a JSON file that was loaded at runtime to populate the page. While this does work fine, it means any error in loading the JavaScript means you just get a blank page.

We should be able to do better.

Defining the data in HTML

HTML itself is actually a pretty good data definition language since all of the data will be human-readable just by virtue of being HTML. In addition, HTML5 allows you to add freeform data attributes to your HTML which means we can select the data pretty easily using JavaScript.

Thus, we could do something like this to define our data:

<article data-item>
    <h2 data-title>Hello, World!</h2>
    <p data-body>
        This is the body of the post.

We can then read this structure using JavaScript to turn it into a data object:

const itemEl = document.querySelector('[data-item]');
const data = {
    title: itemEl.querySelector('[data-title]').textContent,
    body: itemEl.querySelector('[data-body]').innerHTML,

We can then use this data object for whatever purpose we need.

For my tracker, I then cleared the element containing the data and hooked up a Svelte application. This is technically a bit wasteful but I didn't feel like rewriting my entire app right away.

An alternate solution would have been to just add the sorting and filter buttons dynamically, like I did in this CodePen example. The two problems with this were that I didn't want rewrite my entire application, and I don't actually quite know how to reorder elements. (I might have to experiment with this.)

All in all, I'm pretty satisfied with how it works. All of the source code can be found in this GitHub repository for a more in-depth look at how it works.