Skip to content

Serve an app-supplied 404.html for misses - #53

Merged
billf merged 3 commits into
mainfrom
bill/feat/not-found-page
Nov 11, 2026
Merged

billf merged 3 commits into
mainfrom
bill/feat/not-found-page

Conversation

@billf

@billf billf commented Nov 10, 2026 •

Copy link
Copy Markdown
Contributor

Stack: #49 → #53. Independent of the Range stack (#54 → #55 → #56).

A miss is answered with the app's own /404.html and status 404, instead of plain text.

What this PR contains

  • When a site uploads /404.html at its root, a miss is answered with that page and status 404, through both the component handler and registerStaticRoutes. Without the page, the plain-text 404 is kept.
  • Under SPA fallback, extension-less paths still serve index.html. Extension misses such as /missing.js get the page either way. Under --no-spa, every miss gets the page.
  • Pages stored as inherited app storage (from a v1 upgrade) are served too.
  • A failed or rejected fetch for the page falls back to the plain-text 404.
  • Docs: README, INTEGRATION and CHANGELOG describe the page and when --no-spa fits, for multi-page and content sites such as podcast audio and Markdown transcripts.
  • Tests: the page on a miss, SPA precedence, --no-spa, a 404 page stored as a blob without a storage ID, an inherited page, and a failed fetch.

🤖 Generated with Claude Code

@pkg-pr-new

pkg-pr-new Bot commented Nov 10, 2026 •

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/convex/static-hosting/@convex-dev/static-hosting@53

commit: 4404f5e

@billf

billf commented Nov 10, 2026

Copy link
Copy Markdown
Contributor Author

This change is part of the following stack:

Change managed by git-spice.

@billf
billf changed the base branch from bill/fix/mime-types to main November 10, 2026 20:49
billf and others added 3 commits November 10, 2026 12:49
A miss used to return plain text. When the site uploads a 404.html at the
root, a miss is answered with that page and status 404, through both the
component handler and registerStaticRoutes. Under SPA fallback, extension-less
paths still serve index.html, so the page appears for misses such as
/missing.js. Under --no-spa, it appears for every miss. Without the page, the
plain-text 404 is kept.

Documents when --no-spa fits: multi-page and content sites, such as podcast
audio and Markdown transcripts, where unknown URLs should 404.

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Serve inherited app-storage error pages on missing paths and keep the plain-text
fallback when fetching the optional custom page rejects. Cover inherited pages,
missing blobs, and rejected fetches with regression tests.
Run prettier on the two new 404 test blocks, which failed
`prettier --check` (it is not part of `npm run lint`). Reword the
comment in the HTTP handler: a hit still costs one query, but a miss
now runs a second query for the app's 404.html.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@billf
billf force-pushed the bill/feat/not-found-page branch from 91c2f31 to 4404f5e Compare November 11, 2026 00:16
@billf
billf requested a review from ianmacartney November 11, 2026 00:17
@billf
billf marked this pull request as ready for review November 11, 2026 00:17

@ianmacartney ianmacartney left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice!

@billf
billf merged commit b1044cc into main Nov 11, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants