diff --git a/.planning/todos/pending/2026-10-20-branded-error-pages-for-browsers.md b/.planning/todos/pending/2026-10-20-branded-error-pages-for-browsers.md new file mode 100644 index 00000000..e521d3ec --- /dev/null +++ b/.planning/todos/pending/2026-10-20-branded-error-pages-for-browsers.md @@ -0,0 +1,24 @@ +--- +created: 2026-10-20T00:54:00Z +title: Branded HTML error pages for browsers, JSON or plain errors for API calls +area: framework +severity: minor +files: + - modules/surf/overlap.go + - modules/surf/params.go + - modules/surf/uploads.go +g15office: jh5qzjba +--- + +## Problem + +An application without a frontend (for example `bin/demo serve` with no Nuxt site in front) answers a browser at `http://127.0.0.1:8080/` with the stdlib's raw `404 page not found` text. Unmatched routes and other framework-generated errors (404, 405, 500, maintenance) look broken to a person in a browser. WinterCMS and OctoberCMS ship generic error pages, but they are ugly. + +## Solution + +Negotiate the error response per request: + +- **Browser** (`Accept` prefers `text/html`, a navigation request, no `X-Requested-With`/JSON `Accept`, not an API prefix such as `/_/api/`): a self-contained HTML page in the SummerCMS look (summercms.io palette, type and sun logo; inline CSS, no external assets), with the status code, a short human message, a link to `/` and, outside production, request details. +- **API or programmatic call**: keep today's body (plain text or the `wire` JSON error shape) so PHP-compatible contracts and existing clients do not change. + +Covers the ServeMux fallback (unmatched route and method mismatch), `http.NotFound` calls inside surf (`overlap.go`, `params.go`, `uploads.go`) and the recover/500 path. Applications and themes should be able to override the templates (WinterCMS-style `error` / `404` pages), and the backend admin keeps its own SPA errors. Decide which module owns it (surf, or a new beach-named module) and document it in the module README and `docs/`.