Skip to content
Code Recycle

Component · for humans & their agents

Next.js Stale Page Verdict

verified · first-partyactively maintained$0 during beta (was $49)

Your dashboard shows a number from the day you deployed. Measured: the plain fetch is frozen on Next 14, 15 AND 16 — and upgrading does not fix it.

by Code Recycle

Get it free — beta

Every claim on this page is refundable if it is untrue — refund policy.

Verified: 49 tests

Decides whether a Next.js App Router route can serve DATA CAPTURED AT BUILD TIME. Pure function over your route's configuration: no I/O, no Next.js dependency.

Decides whether a Next.js App Router route can serve DATA CAPTURED AT BUILD TIME. Pure function over your route's configuration: no I/O, no Next.js dependency.

Built for Next.js 14, 15 and 16 (MIT). Not affiliated with or endorsed by Vercel.

THE MEASUREMENT. A local origin that INCREMENTS on every read and sends cache-control: no-store. Five routes doing the same await fetch() in a server component, differing only in cache option and route-segment config. next build + next start -- production, not dev. Three requests each. Same code, three majors:

  === Next 14.2.35 ===            === Next 15.5.22 ===          === Next 16.3.0 ===
    plain         20 20 20 FROZEN   plain     12 12 12 FROZEN     plain     13 13 13 FROZEN
    nostore       21 22 23 live     nostore   27 28 29 live       nostore   39 40 41 live
    forcedynamic  20 20 20 FROZEN   forced..  30 31 32 live       forced..  42 43 44 live
    revalidate0   24 25 26 live     reval0    33 34 35 live       reval0    45 46 47 live

THE PLAIN FETCH IS FROZEN ON ALL THREE MAJORS. `await fetch(url)` is what you write when you want live data, and it is what an assistant writes when you ask for live data. In every major tested it produced a page prerendered at build that serves the build-time value forever -- the page served 12 on Next 15 and 13 on Next 16 while the origin ran to 47. The build output for that route reads `○ (Static) prerendered as static content`, which looks like a performance win.

NEXT 15 CHANGED THE FETCH CACHING DEFAULT. THE SYMPTOM DID NOT CHANGE. Someone who upgraded 14 to 15 to fix stale data still has a frozen page, now with the belief that they fixed it.

ON NEXT 14, force-dynamic DOES NOT DO WHAT IT APPEARS TO. It is the first thing everyone reaches for. To separate "the route did not re-render" from "the route re-rendered and the FETCH was cached", the probe prints a per-render marker beside the fetched value:

    DISC render=21810843407708 fetched=20
    DISC render=21810851983000 fetched=20
    DISC render=21810859359291 fetched=20
    -> render marker MOVES / fetched value FROZEN

The route IS executing on every request. The fetch is answered from the Data Cache regardless. force-dynamic controls RENDERING; it did not control the DATA -- and the build output now says `ƒ Dynamic`, so the fix looks confirmed while the data is exactly as stale as before. On 15 and 16 the same route returned live values.

WHAT ACTUALLY WORKED, ON EVERY MAJOR: cache: "no-store" and export const revalidate = 0. Those two were the only configurations measured live on 14, 15 and 16 alike.

RENDERING AND DATA ARE TWO DIFFERENT MECHANISMS, and getting that wrong is easy enough that an EARLIER VERSION OF THIS PACKAGE got it wrong: it told a Next 14 force-dynamic route it was "prerendered during next build" and marked "○ Static", both contradicted by the measurement the same finding cited. Right verdict, wrong explanation. It is pinned now by a test asserting no per-request route is ever described as a build-time snapshot.

IT REPORTS: a static snapshot served forever; force-dynamic's Next 14 no-op; the Data Cache behind it; that upgrading does not fix the snapshot; force-static contradicting changing data; and a positive revalidate that BOUNDS staleness rather than removing it. Worst first -- the symptom your users see leads, the cache that causes it follows.

IT REFUSES rather than guesses, and asks FIRST whether the data can change after the build at all -- because if it cannot, a build-time snapshot is the correct answer and there is nothing to fix.

VERIFIED: 49 tests, measured by running the suite, every mutation observed FAILING before restore -- including two that survived a first pass and exposed real gaps.

DELIVERY: signed download of a hash-verified tarball, immediately on purchase. Permissive licence: unlimited products, unlimited clients, unlimited seats, no attribution, perpetual and irrevocable. One restriction, do not republish the source as source.

Interface

What you call, and what comes back. Types and signatures only — the implementation ships with the source.

  export function evaluateRouteFreshness(route: RouteShape): Verdict;
  export type NextMajor = 14 | 15 | 16 | "unknown";
  export type FetchCache = "default" | "no-store" | "force-cache" | "unknown";
  export type Verdict = | { status: "FRESH";

01Capabilities

Does

  • + Reliability
  • + Cache coherency verification
  • + Render and data freshness

Doesn’t

  • No exclusions declared

02Requirements & stack

Depends on

No declared dependencies

Credentials needed

None declared

Stack

typescript

03Community

No endorsements yet

No verified confirmations yet — be the first.

Confirmations come from verified purchasers, installers, vetted reviewers, or an installation outcome your org reported through the agent tools. They grade quality — security is verified separately, and community votes can never override the security gate.

Open an issue

Sign in to confirm — weight comes from verified usage, not vote count.

0 open · 0 answered · 0 fixed · 1 said it worked

04Trust Passport

Full passport →
–/100

0/0 automated components pass. An automated score is never a security guarantee.

✓ Verified · first-partyreviewed Sep 20, 2026 · re-verification due Dec 19, 2026
  • publisher identity Publisher status verified; 1 verification(s) on file
  • malicious pattern scan No known malicious-behavior patterns across 13 source file(s) plus listing text
  • capability contract All 0 observed capability reference(s) match the declared manifest
  • agent safety scan No injection patterns in agent-readable content
  • provenance No release signature or provenance attestation
  • behavioral sandbox Not performed in this environment — requires the production isolated runner (docs/sandbox-requirements.md). No untrusted code is ever executed on the application host.

Every listing must pass this review before it can be sold, and it is re-run on every release. Verification describes what we checked — it is not a guarantee that the software is safe.

VersionChannelReleasedNotes
1.0.0stableAug 6, 2026First public release.