[PR #1046] [MERGED] fix: support revalidate = false for App route segment config #1048

Closed
opened 2026-05-06 13:11:44 +02:00 by BreizhHardware · 0 comments

📋 Pull Request Information

Original PR: https://github.com/cloudflare/vinext/pull/1046
Author: @NathanDrake2406
Created: 5/4/2026
Status: Merged
Merged: 5/4/2026
Merged by: @james-elicx

Base: mainHead: fix/issue-1041-revalidate-false


📝 Commits (3)

  • 095740d fix: support revalidate = false for App route segment config (#1041)
  • 9ef6046 fix: exclude Infinity from route handler ISR read/write gates
  • 8769b95 Update packages/vinext/src/build/report.ts

📊 Changes

9 files changed (+122 additions, -13 deletions)

View changed files

📝 packages/vinext/src/build/report.ts (+8 -5)
📝 packages/vinext/src/server/app-route-handler-policy.ts (+6 -3)
📝 packages/vinext/src/server/app-route-handler-response.ts (+11 -1)
📝 packages/vinext/src/server/app-segment-config.ts (+9 -3)
📝 tests/app-route-handler-policy.test.ts (+15 -1)
📝 tests/app-route-handler-response.test.ts (+17 -0)
📝 tests/app-segment-config.test.ts (+28 -0)
📝 tests/build-report.test.ts (+20 -0)
tests/fixtures/app-basic/app/revalidate-false-test/page.tsx (+8 -0)

📄 Description

Fixes #1041

Summary

  • extractExportConstNumber now matches false and returns Infinity, mapping export const revalidate = false to "cache indefinitely" — matching Next.js semantics where false means "disable revalidation"
  • resolveRevalidateSeconds in app-segment-config.ts (introduced by #993) handles revalidate = falseInfinity, with correct shortest-wins: finite numeric intervals beat Infinity because any finite interval is shorter than forever
  • Build-time classifiers (classifyLayoutSegmentConfig, classifyAppRoute) correctly classify revalidate = false as static
  • Runtime route handler (getAppRouteHandlerRevalidateSeconds) converts false to Infinity so ISR cache gates correctly enable indefinite caching
  • buildRouteHandlerCacheControl emits STATIC_CACHE_CONTROL for Infinity instead of a malformed s-maxage=Infinity header

Next.js reference

Next.js segment config validation explicitly accepts revalidate = false as a valid value with the semantic "disable revalidation" (= cache indefinitely):

Test plan

Test file New/updated
build-report.test.ts 3 new: extractExportConstNumber(false), classifyLayoutSegmentConfig(false), classifyAppRoute(false)
app-segment-config.test.ts 3 new: false → Infinity, shortest-wins (layout false + page 60), shortest-wins (layout 60 + page false)
app-route-handler-policy.test.ts 1 updated + 3 new: false → Infinity, Infinity cache read/write/header gates
app-route-handler-response.test.ts 2 new: InfinitySTATIC_CACHE_CONTROL for cached response, Infinity → static header
revalidate-false-test/page.tsx New fixture page for integration test

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/cloudflare/vinext/pull/1046 **Author:** [@NathanDrake2406](https://github.com/NathanDrake2406) **Created:** 5/4/2026 **Status:** ✅ Merged **Merged:** 5/4/2026 **Merged by:** [@james-elicx](https://github.com/james-elicx) **Base:** `main` ← **Head:** `fix/issue-1041-revalidate-false` --- ### 📝 Commits (3) - [`095740d`](https://github.com/cloudflare/vinext/commit/095740dc2fdb06701aa94b52114c703548026bdf) fix: support revalidate = false for App route segment config (#1041) - [`9ef6046`](https://github.com/cloudflare/vinext/commit/9ef6046c032de1b0afc76311322dda5b740d2b31) fix: exclude Infinity from route handler ISR read/write gates - [`8769b95`](https://github.com/cloudflare/vinext/commit/8769b958565ffb65f2a3d4b8ff5ae5dfc5c68ffd) Update packages/vinext/src/build/report.ts ### 📊 Changes **9 files changed** (+122 additions, -13 deletions) <details> <summary>View changed files</summary> 📝 `packages/vinext/src/build/report.ts` (+8 -5) 📝 `packages/vinext/src/server/app-route-handler-policy.ts` (+6 -3) 📝 `packages/vinext/src/server/app-route-handler-response.ts` (+11 -1) 📝 `packages/vinext/src/server/app-segment-config.ts` (+9 -3) 📝 `tests/app-route-handler-policy.test.ts` (+15 -1) 📝 `tests/app-route-handler-response.test.ts` (+17 -0) 📝 `tests/app-segment-config.test.ts` (+28 -0) 📝 `tests/build-report.test.ts` (+20 -0) ➕ `tests/fixtures/app-basic/app/revalidate-false-test/page.tsx` (+8 -0) </details> ### 📄 Description Fixes #1041 ## Summary - `extractExportConstNumber` now matches `false` and returns `Infinity`, mapping `export const revalidate = false` to "cache indefinitely" — matching Next.js semantics where `false` means "disable revalidation" - `resolveRevalidateSeconds` in `app-segment-config.ts` (introduced by #993) handles `revalidate = false` → `Infinity`, with correct shortest-wins: finite numeric intervals beat `Infinity` because any finite interval is shorter than forever - Build-time classifiers (`classifyLayoutSegmentConfig`, `classifyAppRoute`) correctly classify `revalidate = false` as `static` - Runtime route handler (`getAppRouteHandlerRevalidateSeconds`) converts `false` to `Infinity` so ISR cache gates correctly enable indefinite caching - `buildRouteHandlerCacheControl` emits `STATIC_CACHE_CONTROL` for `Infinity` instead of a malformed `s-maxage=Infinity` header ## Next.js reference Next.js segment config validation explicitly accepts `revalidate = false` as a valid value with the semantic "disable revalidation" (= cache indefinitely): - **Schema**: [`AppSegmentConfigSchema`](https://github.com/vercel/next.js/blob/canary/packages/next/src/build/segment-config/app/app-segment-config.ts#L135-L137) — `z.union([z.number().int().nonnegative(), z.literal(false)])` - **Type**: [`AppSegmentConfig.revalidate`](https://github.com/vercel/next.js/blob/canary/packages/next/src/build/segment-config/app/app-segment-config.ts#L193) — `number | false` - **Error message**: `"must be a non-negative number or false"` ## Test plan | Test file | New/updated | |-----------|-------------| | `build-report.test.ts` | 3 new: `extractExportConstNumber(false)`, `classifyLayoutSegmentConfig(false)`, `classifyAppRoute(false)` | | `app-segment-config.test.ts` | 3 new: `false → Infinity`, shortest-wins (layout `false` + page `60`), shortest-wins (layout `60` + page `false`) | | `app-route-handler-policy.test.ts` | 1 updated + 3 new: `false → Infinity`, `Infinity` cache read/write/header gates | | `app-route-handler-response.test.ts` | 2 new: `Infinity` → `STATIC_CACHE_CONTROL` for cached response, `Infinity` → static header | | `revalidate-false-test/page.tsx` | New fixture page for integration test | --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
BreizhHardware 2026-05-06 13:11:44 +02:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/vinext#1048
No description provided.