Building a Euros sweepstake website with 11ty

We always have a family sweepstake for the Euros and the World Cup so I thought I'd create a website for it: euros.robwood.uk. This is going to be a brief overview of what I can remember rather than a detailed step-by-step guide. The source-code is here.

The basics

I built this website with 11ty and it uses a simple starter template I'd created.

The data fetching happens in a single data.js file so this data is available globally. When I made a World Cup sweepstake site I split the data files up and imported them. That probably makes sense as a way to organise it better but I decided to chuck them all in one file this time. Who doesn't love a bit of chaos?

The API

I used the free football-data.org API to get all the data for this website.

The main problem I've had is that I haven't been able to read the API using a token on the client without a CORS error.

I don't know if this is something I'm doing wrong or a limit of the free tier. As the documentation shows how make make a request in various programming languages but not JavaScript, I'm assuming it's the latter.

The way around it was to make the fetch request during the build process. As a result, the website would only update when I deployed the site to Netlify. I needed a way to deploy the site daily so the data was at least correct the following day.

Deploying the site daily

Before I decided how I'd do this I needed to set up a Netlify Build Hook first.

I'd previously used the IFTTT service to hook into this Build Hook. Unfortunately, this ability is now part of the 'Pro' tier and is no longer free. I had to look for another way so I decided to give GitHub Actions a go.

I found an article that shows how to trigger a netlify build every day. To create the new workflow in my repo I went to the 'Actions' tab then the 'set up a workflow yourself' link.

The only things I changed in the example code where the build hook URL and the time the workflow is triggered.

This did the job!

Assigning the family members

The API gave me most of what I needed. I wanted to be able to assign a family member to each team when it came to the fixtures, results and standings. I cloned the teams array and created a new property called 'family_member'. I then assigned each team to a family member. I also created an assignFamilyMember function that I could use for the fixture, results and standings.

Graphics

I wanted it to look like an old 8-bit football game but that didn't quite pan out. The main reason was the lack of authentic typefaces that were actually readable.

I created pixel-art style icons for family members and the country flags. I based the family member's heads on those in the 90s football game Sensible Soccer.

I'd planned on using some flag icons I found online but in the end I decided to recreate my own 8-bit style versions (inaccurate aspect ratios and all).

I also used a mono-space font to get close to some kind of retro feel. I'm not sure how well that worked but it's close to the look I was hoping for and is pretty readable.

The PWA

I don't have a lot of experience with PWAs. I wanted to create the minimum needed for a user to be able to add the app icon to their homescreens.

There are two things needed for a PWA (in addition to serving the website over https):

Manifest

This file tells the browser how it should display the app. It includes things like the name, start URL colours and logos (and more). This is in the JSON format and follows a straightforward convention.

Service worker

The service worker file runs in the browser separately to the main app. It can hand network requests, manage the cache and do all sorts of things I haven't really used yet.

It also means I found this trickier to work. I ended up using an example service worker from Google to fulfill the requirements of a PWA.

What I ended up with

A website that does the job. It's far from perfect but it's an improvement on the last sweepstake website I made. I just need to improve it in time for the World Cup in 2026 in North America!