---
id: 31863f16-5f76-479b-be32-61b1107441a6
title: Cloudflare Pages clean-URL redirects break the one-shape canonical URL contract
state: closed
labels:
- area:render
assignees: []
milestone: null
created: 2026-10-27T18:40:05.827762324Z
updated: 2026-10-27T19:53:10.473147998Z
---
## Problem

Cloudflare Pages rewrites HTML routes to extensionless URLs, while `hu13 build` emits `.html` links and `hu13 serve`/nginx serve them directly. The `dist/` is therefore not one canonical shape: every generated page link redirects on Pages.

## Verified reproduction

Wrangler 4.154.0 `wrangler pages dev dist`:

```
GET /issues/index.html     -> 308 Location: /issues/
GET /files/a.txt.html      -> 308 Location: /files/a.txt
GET /raw/evil.html         -> 308 Location: /raw/evil
GET /releases/v1.html      -> 308 Location: /releases/v1
GET /releases/v1/evil.html -> 308 Location: /releases/v1/evil
```

`GET /issues/`, `/files/a.txt`, `/raw/evil`, and `/releases/v1` then return 200. A `_redirects` rule with status 200 cannot override the clean-URL redirect (verified).

This also makes the artifact redirect path security-relevant: #106 is the actual active-content bug, and the redirect is what changes the final URL.

## Impact

- Internal navigation and feed links take a 308 on Pages only.
- Raw HTML downloads redirect on Pages only.
- External canonical URLs (`/issues/index.html`) are not the Pages canonical URL.
- The one-shape requirement is not met even though pages remain reachable.

## Fix options

Pick during convergence: emit extensionless canonical links and adapt `serve`/docs, or add a Pages-side function/worker that preserves `.html`, or explicitly declare Pages redirect behavior acceptable and document the canonical URL difference. Do not rely on `_redirects` to suppress the platform redirect.
