Skip to content
Development

Closing the loop on the Open Source section, and the 404 that couldn't run server code

By Victor Da Luz
astrocloudflarei18ndev-logsite

Two small issues, picked up back to back because they were both loose ends on the Open Source section I’d just finished building: a 404 page that had never been translated, and a blog that didn’t know the section existed.

The 404 page that couldn’t run server code

This site runs on Cloudflare Workers with static assets. When a build has a page prerendered to a plain HTML file, a request for anything that doesn’t match a real route falls through to a single built-in 404 response, served directly from the edge without ever invoking my application code. I’d confirmed this weeks earlier with four separate tests: nested locale-specific 404 files, hand-placed literal files, explicit config flags. None of it mattered. The static-asset layer serves one 404.html, full stop.

The real fix is a flag called run_worker_first, which routes every request through the Worker instead of letting the edge answer directly from static files. That’s a genuine tradeoff: added latency and cost on every page load, not just the rare 404, for the entire site. Not a decision to make quietly inside what looked like a two-line copy fix.

So I didn’t flip it. Instead I kept the 404 page exactly as static as before and moved the localization into the browser. All three languages’ strings ship embedded in the page as plain JSON. A small inline script reads the URL path, works out whether it starts with an /es/ or /pt/ segment, and swaps the heading, description, button text and link, page title, and html lang attribute, all client-side. Zero server cost, because there’s no server involved for that page at all.

The part I almost got wrong: matching on the URL segment, not just checking whether the path starts with “/es”. A real page called /estimates also starts with those two letters. Splitting the path into segments and checking the first one exactly avoided that false positive. I only caught it because I tested that specific path deliberately, not because anything would have failed loudly if I hadn’t.

The blog that didn’t know the section existed

Separately: the dev log and the new Open Source section were built in isolation from each other, with no link between them beyond the nav and footer. I added a pointer on the blog index and wired up something more interesting: package names can now be blog post tags, and if a post carries one, its tag renders as a real link to that package’s page. The package’s page, in turn, lists any dev log posts tagged with its name - the same shape as the project-filtered routes already on the site.

Here’s the part worth being honest about: as of right now, that mechanism does nothing. Not one existing post is tagged with a package name, so the “From the dev log” section on every package page is empty and there’s no tag pill anywhere pointing back. I built it anyway, because the alternative was waiting for the right post to exist before writing the code that would show it, which is backwards. It activates the moment a post gets tagged. Until then it’s quiet infrastructure, not a working feature.

The a11y check that caught something

My new blog-index link sat inside a full sentence of muted gray text, styled to underline only on hover. The accessibility checker flagged it immediately: a link that’s only visually distinct when you’re already hovering it isn’t distinguishable for anyone who can’t see color differences, or isn’t hovering at all.

I’d seen an identical-looking link elsewhere on the site that apparently passed the same check, and my first instinct was to copy its exact classes. Then I noticed I didn’t actually know why that one passed, and I was about to carry a guess forward as if it were a fact. The real fix was simpler than chasing the guess: make the underline permanent instead of hover-only. That’s the fix that’s provably correct, not the one that happens to resemble something else that worked once.

Related reading