Sudbury Rowing Club,

Jamstack site for a sports club

Migrating an established Wordpress site to a fast, cost-effective and manageable jamstack architecture

In completion, this project is:

  • a fast, Next.js frontend
  • a well-structured backend with a queryable API

…and that’s it.

Does it work? Yes, it seems to:

  • FCP: ~18× faster (now 0.6s)
  • Conversions: ~835% more (measured as weekly membership applications)
  • Costs: 3.7% the annual cost of the previous site1

These numbers are pretty dramatic, and they’re only based on one month of ‘new site’ data, but user feedback supports them.

A screenshot of the homepage (on iPad)

It replaced a Wordpress site, which was fundamentally effective but awkward to update (thanks to a sitebuilder plugin).

The goal was to replicate the ‘functionality’ of a massive and esoteric Wordpress site, with a much faster SPA frontend and a much smaller, more manageable SaaS backend. Since all nearly all the data on a vanilla Wordpress install is of unhelpfully of type ‘raw HTML’ in either ‘posts’ or ‘pages’, a big primary task was to design a data structure that massively reduced redundancy.

Cool bits:

  • The contact form is (touch wood) shockingly reliable, as user-friendly as it can be and a massive timesaver for club volunteers. It contends with two issues: 1) there’s no fulltime admin team to forward general enquiries to the right places, and 2) there’s no organisational mail system (i.e. personal addresses are used). This means that users need to be guided into a decsion about the person they want to contact and the resulting API call needs to send a message in a way that doesn’t expose volunteer email addresses. The solution just works and is relatively elegant – i.e. its not many lines of code – but needs to be a lot of atomic modules that run in different contexts.
  • Migration from Wordpress is never easy. I took advantage of the extant Wordpress install to export an archive of Markdown files and images using PHP. Why Markdown? That conversion gracefully strips out esoteric styling and, more importantly, gives access to the unified project. With unified, I did a lot of housekeeping tasks on the archive, then transformed the AST to Portable Text JSON.


  1. How? 1) Running a Wordpress site for a medium-traffic website is incredibly expensive – any practical alternative would have been less costly. 2) Member-specific services were recently moved to a third-party service. This meant that we had far fewer critical interactive elements to worry about and could go cache-crazy. 3) Architecturally, the site is a Next.js-flavoured React app, and much of the work now takes place in the users’ browsers, rather than on our servers (mind you, it still works with JS switched off).