Reading lists aren't big data

When the simple matter of adding a reading list to my website proves less than straightforward, I develop a solution using VueJS and data exported from Goodreads.

Reading lists aren't big data
Photo by Blaz Photo / Unsplash

When thinking about how to rebuild and reorganise my website, I asked my friend and fellow author Mark Timmony what he thought should be on an author’s website. Mark’s far more reader-focused than I am, but I was surprised when he said an author’s reading list was important to readers. I’m not certain why… maybe what one reads is an essential marker of one’s personality or writing influences, or perhaps readers are just searching for recommendations.

Regardless, I decided to add a reading list to my website, figuring it was low-hanging fruit and it might encourage me to read more than I presently do. However, like most endeavours in one’s creative life, things turned out to be slightly more complicated than I thought.

My first idea was to leverage Goodreads, which I’ve used half-heartedly for several years. I thought I could query its API to extract my reading data and simply write a Javascript widget on my website. Alas, Goodreads has effectively deprecated their API as of 2020 and no longer issues new access keys — an odd move for a company owned by Amazon, but okay then…moving on.

My fallback was to use Goodread’s embeddable widgets, but this introduces privacy and tracking issues to my website — and besides, their widgets look like arse, and I don’t want their branding in my garden.

This got me thinking about the viability of rolling a DIY reading list and decoupling myself and my readers from another big-data sponge. Initially, the idea was to create a page in Ghost showcasing the book I’m currently reading using Ghost’s native product widget. However, it didn’t look great, and I decided I wanted more functionality, not merely a generic product showcase.

Starting with some data

What I wanted was something akin to Goodreads, with a list of books for things like currently reading, want to read, read, and those I’ve rated the highest. Fortunately, I was able to kickstart this by exporting my Goodreads data in CSV format. The output was a little messy, and I didn’t need everything it contained, so I wrote a Python script to clean everything and export the data to a nice, clean JSON file.

Here’s the schema I’m using for an individual book; the entire file is just an array of these objects.

{
   "title": "The Blood of the Spear",
   "series": "The Eye of Eternity",
   "series_no": "1",
   "author": "Mark Timmony",
   "author_sort": "Timmony, Mark",
   "isbn": "",
   "rating": "0",
   "pages": "602",
   "published": "2021",
   "date_read": "",
   "date_added": "2021/06/10",
   "status": "currently-reading",
   "review": "",
   "genre": "epic fantasy",
   "medium": "Kobo Reader",
   "amazon": "https://amzn.to/3zMPAvv",
   "apple": "",
   "kobo": "",
   "progress": "",
   "description": "Mark Timmony's debut epic fantasy novel about two brothers, a prophesy and a world on the edge of destruction.",
   "cover": "https://m.media-amazon.com/images/I/51JJVa4nzhS.jpg"
 }

Note, there are holes in my data, but it was enough for me to build the UI and deploy the site as a proof of concept.

Building the UI

I wanted something clean and basic UI — and I wanted to avoid spending too much time. While I could have built it with vanilla HTML, CSS and JavaScript, I decided to knock it up with VueJS, which is my favourite JavaScript framework by a country mile.

I crafted a simple responsive design that shows the (currently) 4 available lists and their status, with a stack of cards containing each book’s data. Clicking each list or header activates the list and hides the rest. The reading now list is shown by default, and as a must for me, the UI automatically shifts to dark mode if the user’s operating system is set to do so.

Rosser's Reads UI
Rosser's Reads UI

As noted, the list is built from a master JSON file I created partially from my Goodreads data. After loading the file into a component, I use JavaScript to filter and sort the data into separate lists exposed to the UI.

I’ll likely tweak the design as time and interest dictate, but for now, I’m happy with it, and the decision to use VueJS means that building on the design and features will be a trivial process.

Deployment

As with all my static web apps, I deployed the site using Netlify, which has a generous free tier that includes web hosting, free HTTPS certificates and an ultra-fast content delivery network.

All I needed to do was import the project from my GitHub repository. Netlify auto-detected the required build settings and rebuilds and deploys the site every time I push new code to the repo’s master branch.

Netlify also supports custom domains, so I opted to use a subdomain of my website, reads.chrisrosser.net, which required adding a CNAME record to my domain name’s DNS record.

Future features

Currently, everything is contained within a single repo, and both site and data are utterly static. For a basic proof of concept (and perhaps beyond), this is more than adequate for my needs. I’m very comfortable updating the data directly in my master JSON file, and the Git-based deployment process is terrific.

Any features I’m likely to add in the short term can all be done with JavaScript. However, if I ever want to make a more dynamic system, perhaps building features that other users may fancy, then replacing the static data file with a RESTful API wouldn’t exactly be difficult.

Concluding thoughts

Well, that was a fun way to spend an afternoon. Any time I get a chance to play with code and decouple from big data, I consider time well spent. I’m starting to feel like the adage of people with hammers, seeing problems as nails. My problems are almost always solvable with JavaScript running on free serverless architecture. It’s a great time to be a developer.

As for the reading list, I’m thrilled with it. For a couple of hours of playful hacking, I’ve created another outlet for my creative passions and given people insight into an important part of my life (reading) without compromising anyone’s privacy or feeding big data.

Anyway, do let me know what you think. If you missed the link, you can find my reading list at reads.chrisrosser.net. If you’re an author, blogger or reader who wants to set something like this up, feel free to fork my repo on Github, and if it’s all over your head, shout out, and I’ll be happy to help.