Skip to content

fix(rewrites): serve static files from public/ when rewrite target is a .html path#217

Open
yunus25jmi1 wants to merge 1 commit intocloudflare:mainfrom
yunus25jmi1:fix/issue-199-rewrites
Open

fix(rewrites): serve static files from public/ when rewrite target is a .html path#217
yunus25jmi1 wants to merge 1 commit intocloudflare:mainfrom
yunus25jmi1:fix/issue-199-rewrites

Conversation

@yunus25jmi1
Copy link

Fixes #199.

Problem

When next.config rewrites() map a clean URL to a static .html file in public/ (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 .html paths.

Root Cause

After afterFiles rewrites resolve a path to *.html, the routing logic in all three server paths would find no matching app/pages route for the .html URL and return 404, without ever checking the filesystem's public/ directory.

Fix

Three server paths updated:

  1. Pages Router dev (packages/vinext/src/index.ts): After afterFiles/fallback rewrites, before the final handler() call, check if the resolved URL points to a file in public/ and serve it directly.

  2. App Router dev (packages/vinext/src/server/app-dev-server.ts): The generated RSC entry now checks public/ for the rewritten pathname before rendering the 404 page. Added a new optional root parameter to generateRscEntry() so the public directory path is embedded in the generated virtual module.

  3. 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 built clientDir (which contains public/ files) before passing to SSR.

Also added a staticMimeType() helper in index.ts to ensure correct Content-Type headers.

Tests

  • Integration tests in app-router.test.ts and pages-router.test.ts: GET /static-html-page (rewritten → /static-html-page.html) returns 200 with correct HTML content and text/html Content-Type.
  • Unit test in app-router.test.ts: generateRscEntry() embeds the public/ path in the generated code.
  • Fixture public/static-html-page.html files added to both app-basic and pages-basic fixtures; next.config rewrites updated.

What async rewrites() flat array does

Per Next.js semantics, when rewrites() returns a flat array, all rules go into afterFiles. vinext already handles this correctly via resolveNextConfig(). This PR fixes the serving of the rewritten destination when it's a static file.

… a .html path

Fixes cloudflare#199.

When next.config rewrites() map a clean URL to a static .html file in
public/ (a common pattern for serving pre-built static pages), vinext
was returning 404 because no Next.js route matches .html paths.

Changes:
- index.ts: Pages Router dev middleware now checks public/ before
  falling through to the SSR handler when the resolved URL has a file
  extension after rewrite processing.
- app-dev-server.ts: Generated RSC entry (App Router dev handler) checks
  public/ for the rewritten pathname before returning the 404 response.
  Accepts a new optional `root` parameter so the public directory path
  can be embedded in the generated virtual module.
- prod-server.ts: After afterFiles and fallback rewrites resolve to a
  path with a file extension, tryServeStatic() is called against the
  built clientDir (which includes public/ files) before passing to SSR.
- index.ts: Added staticMimeType() helper mapping common file extensions
  to MIME types for correct Content-Type headers on served files.

Tests:
- Integration tests in app-router.test.ts and pages-router.test.ts verify
  that GET /static-html-page (rewritten to /static-html-page.html) returns
  200 with correct HTML content and text/html Content-Type.
- Unit test in app-router.test.ts verifies generateRscEntry() embeds the
  public directory path and __nodeFs.statSync static-file lookup code.
- Fixture public/static-html-page.html files added to both app-basic and
  pages-basic fixtures, and their next.config rewrites updated accordingly.
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.

Add support for rewrites

1 participant