Casino Countdowns and Astro

From 2023 to 2024, Blake and I have had to develop a few different versions of what we generally refer to as the “Casino Countdown” site. Having gone through multiple refactors and builds, I decided it makes more business sense to run these sites with Astro and Headless WordPress. Let’s dig in to the reasoning, the gotchas, and how to get started.

Why Headless, Why Astro, Why so many repositories?

When I refactored the 2023/24 NYE page, two things were immediately clear:

  1. This site was built in a hurry
  2. This site doesn’t really need Bootstrap

Moving forward, we built another countdown for the “3 Months, 3 Millionaires” campaign during the summer of 2024, and by the time NYE 24/25 came around, I ran into a key question: what could I delete / overwrite without breaking what I had done previously?

I had refactored the site to make use of some of the same logic, but I realized that if these countdowns were going to be more common, it made sense to decouple everything. I didn’t want to break something for one countdown just to have to fix it for the next one. Eventually, I’d be creating more work for myself (and any other dev).

By building a template repository with the basics of what a countdown page needs, we can quickly spin up a new page without worrying about breaking some other page’s code or carrying over CSS/JS bloat. We can easily borrow components and restyle them (if needed), but we don’t have to tip-toe around a codebase.

Why Astro?

Using Astro solves a few things for us:

  1. Easier to jump into than React or other front-end framework
  2. Minimal setup with components
  3. Ready for client-side interaction (Javascript / React)
  4. Easy CI/CD with their Github Action
  5. Easy composition with JSX and Javascript methods (similar, but less verbose than PHP)

By using Astro, we get the benefit of components, and all our logic is kept in one place. The classic separation of concerns is still maintained, but it’s also really easy to see what’s going on at-a-glance.

Why Headless WordPress?

Since we need to host content like text, images and videos, it makes sense to continue to use WordPress + ACF to build what we need. In this way, we can build a page to design spec, and then if any of the assets change, we can simply swap them out on WordPress and rebuild the Github page. No need to hassle with 3rd party hosting for assets (or uploading huge assets to a Github repo)!

The Main Gotcha

When building with Astro + Headless WordPress, there is a major quirk to be aware of:

If you write a fetch request in a component’s frontmatter to get info from WordPress and then you change that info in WordPress, the page will have to be rebuilt with Github Actions.

Since all frontmatter is rendered to static HTML, the HTML is only updated when the page is built with the Github Action.

If you need to have content be updated dynamically from WordPress on page load, use a frontend framework like React. In other words, instead of building component.astro, build component.tsx and add the client:load directive.

Example

Let’s take the WPImage.astro component. This component expects 1 argument, the imageId. It then fetches the correct data from the WordPress Rest API based on the passed image ID. This all happens when the page is built with a Github Action!

---
export interface Props {
    imageId: number;
}
const { imageId } = Astro.props;
const image = await fetch(
    `https://casinocount.wpengine.com/wp-json/wp/v2/media/${imageId}?_fields[]=source_url`,
).then((res) => res.json());
---

<img
    src={image['source_url']}
    alt=''
    aria-hidden='true'
    loading='eager'
/>

The final <img /> tag will just have a hardcoded source url at something like https://casinocount.wpengine.com/wp-content/uploads/...jpg.

The Template Repository

The Casino Countdown Template Repository is an incredibly lightweight template repo to get you started. Essentially, it has the following:

  • A few Astro components to get the page up and running with some base styles (reset, black bg, etc)
  • A Countdown component to handle the countdown
  • A getTimeRemaining utility function to run the countdown.

That’s really it! Just start up a new repo from this template for each project and start building.

Make sure you go through the steps listed in the readme.md file!

See something inaccurate?