all posts
Our rebuilt website

Why We Rebuilt voatz.com Without a Server

On October 23, 2026, voatz.com stopped being a WordPress site. Here is why we made the change, how we made it without breaking a single link, and what it means for the people who rely on us. A technical section at the end has the details for those who want them.

Why change a website that worked

For the past few years, voatz.com ran on WordPress: a content management system, a database and a set of plugins. It worked well. It is also what a large share of the web runs on, which makes it what a large share of the web’s attackers practise on.

The website has never held election data. Voting happens on the Voatz platform, a separate system with its own infrastructure. But the website carries our name, it is the first place officials and voters look, and a server that executes code on every request, with a database behind it and plugins that need updating, is attack surface.

We hold our election platform to a simple standard: remove whatever does not need to exist. We decided the website should meet the same standard.

What we moved to

Every page of voatz.com is now built ahead of time and stored as plain files, which are served from a global content delivery network. There is no web server to patch. There is no database behind the pages. There is no login page, because there is nothing to log into. When you open a page, you receive a file; nothing runs.

The one interactive part of the site, the contact form, hands your message to a short-lived function that verifies the reCAPTCHA, records the message, sends it to us by email and exits. It cannot be reached in any other way, and it rejects anything that looks like code.

In front of all of this sits a web application firewall that stops common attack patterns at the edge, before they reach anything, and every page is served with the security headers that modern browsers use to protect visitors.

Keeping every link alive

A rebuild is only as good as the links it keeps. Officials bookmark pages, partners link to blog posts, and search engines hold more than ten years of history. So the rule was simple: every address keeps working. Every page, every blog post back to our beginning at the same dated address, every image, every document, and the 326 redirect rules accumulated over the years were compared one by one between the old site and the new one before we switched.

That comparison also turned up something the old site had quietly lost. One hundred and forty-three images in 48 older posts had been broken since an earlier blog server was retired. They are back.

What you might notice: the site is faster, the blog shows more posts at a glance, and analytics loads only after you accept the cookie notice.

What comes next

The new foundation is built to carry more than one language and more than one country from a single source of content, so that an update appears everywhere at once. That is where we are heading. For now, if you notice anything on the site that does not work as you expect, please let us know.


For the technically curious

What follows is the shape of the new site, for readers who like to see under the hood.

Content and build. The WordPress database was exported once into plain JSON files, which now live in version control alongside the site’s source. A static site generator (Astro) turns them into HTML, CSS and a few small scripts. There is no client-side framework. The original theme’s stylesheet was kept as-is so that the new pages are pixel-for-pixel the old ones; jQuery, Bootstrap’s JavaScript and every plugin script were replaced by a few hundred lines of plain JavaScript.

Hosting. The built files sit in Amazon S3 behind CloudFront, reachable only through the distribution. A small function at the edge handles clean URLs, the redirect map, the www-to-apex redirect and a blanket refusal of WordPress paths such as wp-login.php, which are now the most reliable sign that a request is a scanner rather than a person. A response headers policy adds HTTP Strict Transport Security with preload, frame and content-type protections, a referrer policy and a permissions policy to every response.

Contact form. The form posts to an API Gateway endpoint backed by a Node.js function running on ARM. It validates the fields, verifies the reCAPTCHA token, writes a record to DynamoDB that expires after 90 days, and sends the message through Amazon SES. Submissions containing HTML tags, script, event handlers or scanner callback domains are refused before any of that happens.

Edge protection. AWS WAF runs the managed core rule set, the known-bad-inputs rules and an IP reputation list in front of every environment, with a rate limit on the API. Blocked requests get the ordinary 404 page.

Infrastructure as code. Everything above is defined in Terraform, so staging and production are identical by construction. Every change, including this post, is published to a staging site first and to voatz.com only after review.

Parity. Before the switch, a crawler compared 308 addresses, 326 redirect rules and every image in every post between the old and new sites, and reported each difference for review.

Privacy. Fonts are self-hosted, so no request leaves for a font service. Analytics, embedded tweets and video players load only after cookie consent, and the video players use their privacy-enhanced addresses.

What is deliberately not there. A web server. A database behind the pages. A content management login. Plugins. Any code that runs on request, other than the contact function.

If you work in this area and have questions or suggestions about any of it, please reach out via the contact form.

Technology
all posts
Follow @Voatz