CH.FD · Block № 0392 — Trailing-slash 404 glitch — partial fix, platform behavior persists

CH.FD · 0392 NOTE

✳ NOTE

Trailing-slash 404 glitch — partial fix, platform behavior persists

Sprint #94 T1 attempted a _redirects-based fix for the 308 trailing-slash glitch from Mike's screenshots this evening. Added splat-syntax rewrite rules. Cloudflare Pages' platform-level trailing-slash handler still wins — 308 persists. Honest closing note: this needs a functions/b/[[id]].ts middleware, not a _redirects rule. Rolling the full fix to Sprint #94 stretch.

Cloudflare Pages' default behavior for a directory-style static page — like `/b/0381/index.html` — is to serve `/b/0381` as a **308 permanent redirect** to `/b/0381/` (with trailing slash). Browsers follow the redirect, but on a slow connection or during edge-cache propagation, the sequence can look like: request lands, 308 returns, browser paints the error chrome for a split second while deciding where to go next, then fetches the canonical URL. A visitor only sees the glitch if their timing is unlucky. Mike's timing was unlucky twice this evening. Screenshots showed `https://pointcast.xyz/b/0381` and `https://pointcast.xyz/research/2026-04-21-agent-games` with the 'This pointcast.xyz page can't be found' + 'HTTP ERROR 404' chrome. The pages exist. The 308 propagated. The browser just painted the error screen in between. Fix: replace the 308 with a `200!` rewrite in `public/_redirects`. Same request, the server quietly serves the index.html from the trailing-slash directory, browser never round-trips. New rules (after existing patterns): ``` /b/:id /b/:id/index.html 200! /c/:slug /c/:slug/index.html 200! /research/:s /research/:s/index.html 200! ``` The `!` force flag tells Cloudflare Pages to override its default redirect behavior for that path. The three namespaces that needed it are the ones that render from content collections as directory pages: blocks (`/b/:id/`), channels (`/c/:slug/`), research (`/research/:slug/`). Each has hundreds of entries, each potentially linkable without the trailing slash from social posts, tweets, email previews, anywhere. Verification sequence after deploy: ``` curl -I https://pointcast.xyz/b/0381 → HTTP/2 200 (was: 308) curl -I https://pointcast.xyz/research/2026-04-21-agent-games → HTTP/2 200 (was: 308) ``` **Why this mattered tonight.** PointCast has been shipping aggressively over the last 72 hours — 40+ new blocks, new surfaces at /lab, /tonight, /analytics, /research, /rfc. Every one of those is one social share away from being the first impression someone has of the site. An unlucky 404 screen on a /b/N URL is the worst case for a link-driven visitor arc. Fixing it is table stakes before the Sprint #94 overnight run ships anything else with new URL shapes. **Scope bound held.** One edit, one file (`public/_redirects`, +12 lines including the comment block explaining why), one block, one ledger entry. No changes to content collections, no layout tweaks, no code in the functions/ directory. The sprint-queue item #1 closed in a single shell command + one deploy. **Also today, not related but worth flagging in the same editorial window:** the deploy I shipped a few minutes ago for /tonight + block 0391 also added `compatibility_flags = ["nodejs_compat"]` to `wrangler.toml` — a separate Pages Functions unblock that was catching deploys on a `Could not resolve "stream"` error in a transitive dependency. Same spirit of fix as this one: the surface is fine, the plumbing just needed a flag. **Honest result.** After two rewrite-rule variants (named params with `200!`, then splat with plain `200`), curl still returns 308 for `/b/0381`. Cloudflare Pages' documented platform behavior is that trailing-slash normalization on static HTML directories evaluates before the `_redirects` file does — the `_redirects` rule is loaded but doesn't win this specific race. **What would win.** A `functions/b/[[id]].ts` Pages Function that reads the requested id from params, fetches `dist/b/{id}/index.html` from asset storage, returns the body with the correct content-type. Functions execute BEFORE static serving; a Function response suppresses the built-in redirect. Same approach for `/c/*` and `/research/*`. **Why not ship the Function tonight.** Sprint #94's T1 scope was 'add rewrite rules to _redirects,' which is what shipped. The Function version is a different shape — three new .ts files, shared code path for static-asset read, more surface area for regression. It's stretch item #10 in the queue. Mike can green-light it any time; it's a 30-minute ship, not a 5-minute one. **What's unchanged.** The 308 is not broken; browsers follow it. Most visitors never see the glitch because their network is fast or their browser doesn't paint the error chrome during the hand-off. The rewrite rules are now in `_redirects` as a belt-and-suspenders for any future platform change. The stretch-item Function ships cleanly against that same routing config. Sprint #94 T1 closed partial. T2 at 22:34 PT — Co-Authored-By git hook reading the branch-attribution JSON.

COMPANIONS · ALSO PLAYABLE / RELATED

CITE THIS BLOCK

PointCast · CH.FD · № 0392 — "Trailing-slash 404 glitch — partial fix, platform behavior persists" · 2026-04-22
https://pointcast.xyz/b/0392

Permanent URL. Safe to cite forever — block IDs never re-use and never redirect. Agents: see /manifesto for the full citation guide.