← All work03 / 2022

Hernando Votes Newsletter

A bilingual newsletter site that turns live election data into charts and stats.

I made this single-page website for the Hernando County Supervisor of Elections. They had been publishing a pdf newsletter regularly, and distributing it digitally. Since it wasn’t being printed anyway, I figured it would work better as a website. It was my first big project with Astro, and I learned a lot from it.

What was challenging?

Data manipulation. I was digging through the main hernandovotes.gov website and found that there are dynamically updated election stats throughout the site. By searching through the source files and network requests, I found that all this data comes from one source, which is public (albeit hidden in the source code).

I hadn’t worked with an API on this scale before, and there was a lot of data to sort through, so it was a big step at the time. All of the stats in the newsletter are pulled from the json, most have to be calculated from the mass of data in the file.

{
  "Summary": {
    "TotalRegisteredVoters": 146758,
    "ElectionName": "2022 Primary Election",
    "ElectionDate": "08/23/2022",
    "LastUpdatedTime": "2022-09-06T03:50:02.5093378+00:00",
    "CountyName": "HERNANDO",
    "FvrsElectionNumber": 26905
  },
  "PrecinctSplit": {},
  "Location": {},
  "HideTypes": [],
  "Turnout": {
    "DateType": {},
    "PartyType": {},
    "LocationParty": {
      "EarlyVoting": {},
      "ElectionDay": {}
    },
    "PrecinctType": {}
  }
}

This is a simplified version of the JSON I worked with. The original was almost 900 lines long. The output data is placed in cards or charts, which are built using components.

Charts. I also wanted to show the data visually, so I used Chart.js, which creates interactive HTML5 charts. I also added a noscript backup, in case the browser had Javascript disabled, so the charts could be loaded via image. I hadn’t worked with charts before, so there was a lot to learn.

Translation. One of the major features was internationalization (aka. i18n), which allowed the visitor to read the newsletter in Spanish. Each section was translated individually as components, which made the codebase more complex. Since translation was the last step, it had to be redone for every new issue. If I built something similar again, I’d spend more time making it clean and easy to update.

Fonts. Custom fonts raised a licensing question I hadn’t faced before. I already had a personal license for the headline font (MADE Outer Sans), but a government project needs a different one. I emailed the publisher, and they gave me permission to use it for free. It was an easy fix, but a good reminder to check licenses early.

Image compression. At the time, I didn’t think Astro’s image integration was ready for production, so I used Gumlet for image optimization. Looking back, this wasn’t a great solution. Gumlet optimizes each image on request, so every image takes an extra second or so to load.

To work around the delay, I lazy-loaded every image outside the first screen. That shortened the page load, but it also meant images didn’t start loading until they came into view.

This approach also causes visible glitches on page load. I made the logo as an SVG, but Gumlet converts it to WebP, which leaves a blank spot in the header for a moment and shifts the layout. The background is also blank until it finishes processing. Fixing both would noticeably improve the experience.

The GTmetrix numbers are still decent:

GTmetrix screenshot

Visit an archive of the project: hcsoe-newsletter-project.vercel.app