mirror of
https://github.com/cloudflare/vinext.git
synced 2026-05-09 08:25:34 +02:00
[PR #940] [MERGED] fix(app-router): return 405 for non-action mutations to static pages #966
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#966
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/940
Author: @NathanDrake2406
Created: 4/28/2026
Status: ✅ Merged
Merged: 4/28/2026
Merged by: @james-elicx
Base:
main← Head:nathan/app-page-method-405📝 Commits (2)
1b9988afix(app-router): return 405 for non-action mutations to static pagesbc96857fix(app-router): preserve 405 allow header📊 Changes
5 files changed (+288 additions, -0 deletions)
View changed files
📝
packages/vinext/src/entries/app-rsc-entry.ts(+17 -0)➕
packages/vinext/src/server/app-page-method.ts(+64 -0)📝
tests/__snapshots__/entry-templates.test.ts.snap(+96 -0)➕
tests/app-page-method.test.ts(+97 -0)📝
tests/app-router.test.ts(+14 -0)📄 Description
What this changes
Static and SSG App Router page routes now return
405 Method Not AllowedwithAllow: GET, HEADfor non-action mutation requests instead of rendering the page.Why
Next.js has an explicit static/SSG page guard that returns 405 for non-action, non-GET/HEAD page requests: base-server.ts#L2274-L2289.
That guard intentionally excludes possible server action requests, using the same request-shape semantics defined in server-action-request-meta.ts#L26-L43. Next.js also covers the behavior in the prerender suite: prerender.test.ts#L564-L572.
Vinext already handled route handlers and server actions, but a plain
POSTorPUTto a static App Router page fell through to page rendering.Approach
server/app-page-method.tsfor the page method policy so the generated RSC entry stays thin.force-dynamicandrevalidate = 0).Validation
vp test run tests/app-page-method.test.ts tests/app-router.test.ts tests/entry-templates.test.tsvp check packages/vinext/src/server/app-page-method.ts packages/vinext/src/entries/app-rsc-entry.ts tests/app-page-method.test.ts tests/app-router.test.ts tests/entry-templates.test.tsvp run vinext#buildRisk
The static/SSG classification uses the route metadata currently available in the App Router entry. It preserves explicit dynamic opt-outs and server action requests, and it can become more exact as vinext records richer build-time static classification metadata.
🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.