mirror of
https://github.com/cloudflare/vinext.git
synced 2026-05-09 08:25:34 +02:00
[PR #217] fix(rewrites): serve static files from public/ when rewrite target is a .html path #398
Labels
No labels
enhancement
enhancement
good first issue
help wanted
nextjs-tracking
nextjs-tracking
pull-request
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
starred/vinext#398
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
📋 Pull Request Information
Original PR: https://github.com/cloudflare/vinext/pull/217
Author: @yunus25jmi1
Created: 3/1/2026
Status: 🔄 Open
Base:
main← Head:fix/issue-199-rewrites📝 Commits (10+)
506d825fix: serve static HTML files from public/ after rewrites (issue #199)7d3786fMerge remote-tracking branch 'upstream/main' into fix/issue-199-rewritescc56d2caddress bonk review: hoist resolvedPublicDir, log non-ENOENT errors, add wasm MIME type, document leading-slash assumptionc4835eeaddress bonk review: hoist __publicDir to module scope, add fallback rewrite static file tests945b9ccfix: use path.resolve for publicDir consistency with index.tsa6852a1Update packages/vinext/src/index.tse629695Update packages/vinext/src/index.tsa9013cdMerge upstream/main into fix/issue-199-rewritescab6115fix syntax errors in merge resolutione30bd8bfix: update snapshots and formatting for static file serving feature📊 Changes
17 files changed (+710 additions, -12 deletions)
View changed files
📝
packages/vinext/src/entries/app-rsc-entry.ts(+57 -0)📝
packages/vinext/src/index.ts(+76 -3)➕
packages/vinext/src/server/mime.ts(+47 -0)📝
packages/vinext/src/server/prod-server.ts(+40 -8)📝
tests/__snapshots__/entry-templates.test.ts.snap(+289 -1)📝
tests/app-router.test.ts(+60 -0)➕
tests/fixtures/app-basic/app/action-dynamic-redirect/page.tsx(+23 -0)📝
tests/fixtures/app-basic/app/actions/actions.ts(+8 -0)📝
tests/fixtures/app-basic/next.config.ts(+6 -0)➕
tests/fixtures/app-basic/public/auth/no-access.html(+9 -0)➕
tests/fixtures/app-basic/public/fallback-page.html(+10 -0)➕
tests/fixtures/app-basic/public/static-html-page.html(+10 -0)📝
tests/fixtures/pages-basic/next.config.mjs(+15 -0)➕
tests/fixtures/pages-basic/public/auth/no-access.html(+9 -0)➕
tests/fixtures/pages-basic/public/fallback-page.html(+10 -0)➕
tests/fixtures/pages-basic/public/static-html-page.html(+10 -0)📝
tests/pages-router.test.ts(+31 -0)📄 Description
Fixes #199.
Problem
When
next.configrewrites() map a clean URL to a static.htmlfile inpublic/(a common pattern for serving pre-built static pages like/auth/no-access→/auth/no-access.html), vinext was returning 404 because no Next.js route matches.htmlpaths.Root Cause
After
afterFilesrewrites resolve a path to*.html, the routing logic in all three server paths would find no matching app/pages route for the.htmlURL and return 404, without ever checking the filesystem'spublic/directory.Fix
Three server paths updated:
Pages Router dev (
packages/vinext/src/index.ts): After afterFiles/fallback rewrites, before the finalhandler()call, check if the resolved URL points to a file inpublic/and serve it directly.App Router dev (
packages/vinext/src/server/app-dev-server.ts): The generated RSC entry now checkspublic/for the rewritten pathname before rendering the 404 page. Added a new optionalrootparameter togenerateRscEntry()so the public directory path is embedded in the generated virtual module.Production server (
packages/vinext/src/server/prod-server.ts): After afterFiles rewrites and after fallback rewrites produce a path with a file extension,tryServeStatic()is called against the builtclientDir(which containspublic/files) before passing to SSR.Also added a
staticMimeType()helper inindex.tsto ensure correctContent-Typeheaders.Tests
app-router.test.tsandpages-router.test.ts:GET /static-html-page(rewritten →/static-html-page.html) returns 200 with correct HTML content andtext/htmlContent-Type.app-router.test.ts:generateRscEntry()embeds thepublic/path in the generated code.public/static-html-page.htmlfiles added to bothapp-basicandpages-basicfixtures;next.configrewrites updated.What async rewrites() flat array does
Per Next.js semantics, when
rewrites()returns a flat array, all rules go intoafterFiles. vinext already handles this correctly viaresolveNextConfig(). This PR fixes the serving of the rewritten destination when it's a static file.🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.