← All posts
Infrastructure
1 min read

A 308 that sent every link home

Reloading any page in the app, or opening a shared link, landed on Today. The SPA rewrite rules pointed at /index.html, and Cloudflare Pages redirects that to /. It had been true for every deployment.


While verifying the new day view in production, /day/2026-10-02 came back 404, and /search came back with a 308 to /. Checking older routes showed it wasn’t new: /habits did the same, on every deployment going back as far as the list went.

What was happening

The app is a single-page app on Cloudflare Pages. A generated _redirects file rewrites each known route prefix to the app shell:

/habits   /index.html 200
/habits/* /index.html 200

A 200 rule is meant to serve the target file in place, with no redirect. But Pages also normalises URLs: a request for /index.html is redirected to / with a 308. That normalisation applied to the rewrite target too. So every deep link became a redirect to the home page.

In daily use it hid well. Moving around inside the app never reloads the page, so it worked. It only broke on a reload, a link opened from outside, or a home-screen shortcut, and each of those looks like a minor glitch rather than a bug.

The fix

Rewrite to / instead, which serves the same file:

/habits   / 200
/habits/* / 200

It went to a preview branch first. All six routes tested returned 200 with the app shell, including nested routes and query strings. An unknown path still returned a real 404, and robots.txt was still plain text. Then it was merged.

The lesson

Checking a route with curl that follows redirects, or in a browser, would have shown the page loading and nothing wrong. Checking the status code without following redirects is what showed the 308. Deep-link checks now look at the status, not just the final page.

AlzyWelzy

Building PaceStreak. GitHub

Related

  • Infrastructure

    How much one small server carries

    A load test of signed-in users doing what the app does all day, the first capacity numbers, and why production numbers from India say more about distance than about the server.

    2 min
  • Design

    Keyboard first, and thumb first

    A command palette, G-then-a-letter shortcuts, swipe and long-press on habits, pull to refresh, and why each one is a shortcut on top of a button rather than the only way in.

    2 min

Build the habit. Keep the week.

PaceStreak is a habit and streak tracker for training and everything else worth doing regularly.