nextjs - ✅(Solved) Fix Cache Components don't cache with empty static params array (Next.js 15/16) [1 pull requests, 9 comments, 4 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
vercel/next.js#84404Fetched 2026-04-08 02:19:28
View on GitHub
Comments
9
Participants
4
Timeline
19
Reactions
0
Author
Timeline (top)
commented ×9mentioned ×2subscribed ×2closed ×1

Fix Action

Fixed

PR fix notes

PR #84280: feat(breaking): Hard Deprecate PPR Configuration

Description (problem / solution / changelog)

This hard deprecates the experimental.ppr configuration, requiring users to opt-in instead via experimental.cacheComponents. This does mean that the previous experimental.ppr = "incremental" will no longer be supported.

NAR-433

Changed files

  • .github/workflows/build_and_test.yml (modified, +0/-1)
  • package.json (modified, +1/-1)
  • packages/next/errors.json (modified, +2/-1)
  • packages/next/src/server/config-shared.ts (modified, +3/-3)
  • packages/next/src/server/config.test.ts (modified, +11/-40)
  • packages/next/src/server/config.ts (modified, +34/-102)
  • packages/next/src/shared/lib/errors/canary-only-config-error.ts (renamed, +1/-1)
  • packages/next/src/shared/lib/errors/hard-deprecated-config-error.ts (added, +9/-0)
  • test/development/acceptance-app/hydration-error.test.ts (modified, +1/-1)
  • test/development/app-dir/source-mapping/next.config.js (modified, +1/-1)
  • test/development/app-dir/source-mapping/source-mapping.test.ts (modified, +2/-1)
  • test/e2e/app-dir/app-static/app-static.test.ts (modified, +6/-6)
  • test/e2e/app-dir/app-static/app/dynamic-error/[id]/page.js (modified, +1/-1)
  • test/e2e/app-dir/app/index.test.ts (modified, +2/-7)
  • test/e2e/app-dir/custom-cache-control/custom-cache-control.test.ts (modified, +1/-1)
  • test/e2e/app-dir/dynamic-data/dynamic-data.test.ts (modified, +4/-4)
  • test/e2e/app-dir/metadata-static-generation/metadata-static-generation.test.ts (modified, +1/-1)
  • test/e2e/app-dir/metadata-streaming-static-generation/metadata-streaming-static-generation.test.ts (modified, +1/-1)
  • test/e2e/app-dir/next-after-app-deploy/index.test.ts (modified, +1/-1)
  • test/e2e/app-dir/not-found/default/default.test.ts (modified, +1/-1)
  • test/e2e/app-dir/ppr-errors/next.config.js (modified, +1/-1)
  • test/e2e/app-dir/ppr-errors/ppr-errors.test.ts (modified, +2/-1)
  • test/e2e/app-dir/ppr-full/next.config.js (modified, +1/-1)
  • test/e2e/app-dir/ppr-full/ppr-full.test.ts (modified, +2/-1)
  • test/e2e/app-dir/ppr-history-replace-state/next.config.js (modified, +1/-1)
  • test/e2e/app-dir/ppr-incremental/app/disabled/page.jsx (removed, +0/-2)
  • test/e2e/app-dir/ppr-incremental/app/dynamic/[slug]/page.jsx (removed, +0/-1)
  • test/e2e/app-dir/ppr-incremental/app/dynamic/disabled/[slug]/page.jsx (removed, +0/-2)
  • test/e2e/app-dir/ppr-incremental/app/dynamic/enabled/[slug]/page.jsx (removed, +0/-2)
  • test/e2e/app-dir/ppr-incremental/app/enabled/page.jsx (removed, +0/-2)
  • test/e2e/app-dir/ppr-incremental/app/favicon.ico (removed, +0/-0)
  • test/e2e/app-dir/ppr-incremental/app/layout.jsx (removed, +0/-7)
  • test/e2e/app-dir/ppr-incremental/app/nested/disabled/[slug]/page.jsx (removed, +0/-1)
  • test/e2e/app-dir/ppr-incremental/app/nested/disabled/disabled/[slug]/page.jsx (removed, +0/-2)
  • test/e2e/app-dir/ppr-incremental/app/nested/disabled/enabled/[slug]/page.jsx (removed, +0/-2)
  • test/e2e/app-dir/ppr-incremental/app/nested/disabled/layout.jsx (removed, +0/-5)
  • test/e2e/app-dir/ppr-incremental/app/nested/enabled/[slug]/page.jsx (removed, +0/-1)
  • test/e2e/app-dir/ppr-incremental/app/nested/enabled/disabled/[slug]/page.jsx (removed, +0/-2)
  • test/e2e/app-dir/ppr-incremental/app/nested/enabled/enabled/[slug]/page.jsx (removed, +0/-2)
  • test/e2e/app-dir/ppr-incremental/app/nested/enabled/layout.jsx (removed, +0/-5)
  • test/e2e/app-dir/ppr-incremental/app/omitted/[slug]/page.jsx (removed, +0/-2)
  • test/e2e/app-dir/ppr-incremental/app/omitted/disabled/[slug]/page.jsx (removed, +0/-3)
  • test/e2e/app-dir/ppr-incremental/app/omitted/enabled/[slug]/page.jsx (removed, +0/-3)
  • test/e2e/app-dir/ppr-incremental/app/page.jsx (removed, +0/-1)
  • test/e2e/app-dir/ppr-incremental/app/static/page.jsx (removed, +0/-3)
  • test/e2e/app-dir/ppr-incremental/lib/page.jsx (removed, +0/-30)
  • test/e2e/app-dir/ppr-incremental/next.config.js (removed, +0/-8)
  • test/e2e/app-dir/ppr-incremental/ppr-incremental.test.ts (removed, +0/-205)
  • test/e2e/app-dir/ppr-metadata-blocking/next.config.js (modified, +1/-1)
  • test/e2e/app-dir/ppr-metadata-blocking/ppr-metadata-blocking-ppr-fallback.test.ts (modified, +2/-1)
  • test/e2e/app-dir/ppr-metadata-streaming/next.config.js (modified, +1/-1)
  • test/e2e/app-dir/ppr-metadata-streaming/ppr-metadata-streaming.test.ts (modified, +2/-1)
  • test/e2e/app-dir/ppr-middleware-rewrite-force-dynamic-ssg-dynamic-params/next.config.js (modified, +1/-1)
  • test/e2e/app-dir/ppr-middleware-rewrite-force-dynamic-ssg-dynamic-params/ppr-middleware-rewrite-force-dynamic-ssg-dynamic-params.test.ts (modified, +2/-1)
  • test/e2e/app-dir/ppr-navigations/avoid-popstate-flash/next.config.js (modified, +1/-1)
  • test/e2e/app-dir/ppr-navigations/incremental/app/[locale]/about/page.jsx (removed, +0/-11)
  • test/e2e/app-dir/ppr-navigations/incremental/app/[locale]/layout.jsx (removed, +0/-19)
  • test/e2e/app-dir/ppr-navigations/incremental/app/[locale]/page.jsx (removed, +0/-9)
  • test/e2e/app-dir/ppr-navigations/incremental/app/[locale]/static/page.jsx (removed, +0/-9)
  • test/e2e/app-dir/ppr-navigations/incremental/app/layout.jsx (removed, +0/-3)
  • test/e2e/app-dir/ppr-navigations/incremental/app/page.jsx (removed, +0/-7)
  • test/e2e/app-dir/ppr-navigations/incremental/components/page.jsx (removed, +0/-41)
  • test/e2e/app-dir/ppr-navigations/incremental/incremental.test.ts (removed, +0/-78)
  • test/e2e/app-dir/ppr-navigations/incremental/next.config.js (removed, +0/-5)
  • test/e2e/app-dir/ppr-navigations/prefetch-navigation/next.config.js (modified, +1/-1)
  • test/e2e/app-dir/ppr-navigations/prefetch-navigation/prefetch-navigation.test.ts (modified, +2/-1)
  • test/e2e/app-dir/ppr-navigations/search-params/next.config.js (modified, +1/-1)
  • test/e2e/app-dir/ppr-navigations/search-params/search-params.test.ts (modified, +2/-1)
  • test/e2e/app-dir/ppr-navigations/stale-prefetch-entry/next.config.js (modified, +1/-1)
  • test/e2e/app-dir/ppr-partial-hydration/next.config.ts (modified, +1/-3)
  • test/e2e/app-dir/ppr-unstable-cache/next.config.js (modified, +1/-1)
  • test/e2e/app-dir/ppr/next.config.js (modified, +1/-1)
  • test/e2e/app-dir/ppr/ppr.test.ts (modified, +2/-1)
  • test/e2e/app-dir/react-max-headers-length/next.config.js (modified, +1/-1)
  • test/e2e/app-dir/rewrite-headers/rewrite-headers.test.ts (modified, +10/-10)
  • test/e2e/app-dir/rsc-basic/rsc-basic.test.ts (modified, +3/-2)
  • test/e2e/app-dir/rsc-redirect/rsc-redirect.test.ts (modified, +8/-7)
  • test/e2e/app-dir/segment-cache/client-only-opt-in/app/dynamic-with-ppr/loading.tsx (removed, +0/-3)
  • test/e2e/app-dir/segment-cache/client-only-opt-in/app/dynamic-with-ppr/page.tsx (removed, +0/-8)
  • test/e2e/app-dir/segment-cache/client-only-opt-in/app/dynamic-without-ppr/loading.tsx (removed, +0/-3)
  • test/e2e/app-dir/segment-cache/client-only-opt-in/app/dynamic-without-ppr/page.tsx (removed, +0/-6)
  • test/e2e/app-dir/segment-cache/client-only-opt-in/app/layout.tsx (removed, +0/-11)
  • test/e2e/app-dir/segment-cache/client-only-opt-in/app/page.tsx (removed, +0/-35)
  • test/e2e/app-dir/segment-cache/client-only-opt-in/app/static/page.tsx (removed, +0/-3)
  • test/e2e/app-dir/segment-cache/client-only-opt-in/client-only-opt-in.test.ts (removed, +0/-134)
  • test/e2e/app-dir/segment-cache/client-only-opt-in/components/link-accordion.tsx (removed, +0/-33)
  • test/e2e/app-dir/segment-cache/client-only-opt-in/next.config.js (removed, +0/-11)
  • test/e2e/app-dir/segment-cache/conflicting-routes/app/[lang]/[teamSlug]/[projectSlug]/monitoring/page.jsx (removed, +0/-9)
  • test/e2e/app-dir/segment-cache/conflicting-routes/app/[lang]/[teamSlug]/~/monitoring/page.jsx (removed, +0/-7)
  • test/e2e/app-dir/segment-cache/conflicting-routes/app/[lang]/layout.jsx (removed, +0/-11)
  • test/e2e/app-dir/segment-cache/conflicting-routes/app/[lang]/loading.jsx (removed, +0/-3)
  • test/e2e/app-dir/segment-cache/conflicting-routes/app/[lang]/page.jsx (removed, +0/-9)
  • test/e2e/app-dir/segment-cache/conflicting-routes/app/new/[teamSlug]/layout.jsx (removed, +0/-7)
  • test/e2e/app-dir/segment-cache/conflicting-routes/app/new/[teamSlug]/page.tsx (removed, +0/-3)
  • test/e2e/app-dir/segment-cache/conflicting-routes/app/prefetch-tests/[id]/page.jsx (removed, +0/-9)
  • test/e2e/app-dir/segment-cache/conflicting-routes/app/prefetch-tests/dynamic/page.jsx (removed, +0/-7)
  • test/e2e/app-dir/segment-cache/conflicting-routes/app/prefetch-tests/layout.jsx (removed, +0/-7)
  • test/e2e/app-dir/segment-cache/conflicting-routes/app/prefetch-tests/page.jsx (removed, +0/-9)
  • test/e2e/app-dir/segment-cache/conflicting-routes/conflicting-routes.test.ts (removed, +0/-71)
  • test/e2e/app-dir/segment-cache/conflicting-routes/next.config.js (removed, +0/-11)

Code Example

Operating System:
  Platform: darwin
  Arch: arm64
  Version: Darwin Kernel Version 25.0.0: Wed Sep 17 21:35:32 PDT 2025; root:xnu-12377.1.9~141/RELEASE_ARM64_T6020
  Available memory (MB): 65536
  Available CPU cores: 12
Binaries:
  Node: 22.19.0
  npm: 10.9.3
  Yarn: 1.22.22
  pnpm: 10.15.1
Relevant Packages:
  next: 15.6.0-canary.38 // Latest available version is detected (15.6.0-canary.38).
  eslint-config-next: 15.6.0-canary.38
  react: 19.1.0
  react-dom: 19.1.0
  typescript: 5.9.2
Next.js Config:
  output: N/A
RAW_BUFFERClick to expand / collapse

Link to the code that reproduces this issue

https://github.com/cornedor/cache-components-route/tree/static-params

To Reproduce

  1. Open https://cache-components-route-git-static-params-cornedors-projects.vercel.app/nl/foo
  2. ... will be shown shortly, then the rendered content.
  3. Refresh the page.
  4. ... will be shown shortly, then the rendered content.

Current vs. Expected behavior

The loader is shown every time you open the page. Even though, generateStaticParams returns an empty array. The expected behavior is that the content is statically rendered on the server the first time it is visited.

From the docs: "To statically render all paths the first time they're visited, return an empty array"

This works as expected in dev mode.

Opening https://cache-components-route-git-static-params-cornedors-projects.vercel.app/nl shows that defining a list of static params does work as expected. The page shows that the NL language is used, as defined in the

Provide environment information

Operating System:
  Platform: darwin
  Arch: arm64
  Version: Darwin Kernel Version 25.0.0: Wed Sep 17 21:35:32 PDT 2025; root:xnu-12377.1.9~141/RELEASE_ARM64_T6020
  Available memory (MB): 65536
  Available CPU cores: 12
Binaries:
  Node: 22.19.0
  npm: 10.9.3
  Yarn: 1.22.22
  pnpm: 10.15.1
Relevant Packages:
  next: 15.6.0-canary.38 // Latest available version is detected (15.6.0-canary.38).
  eslint-config-next: 15.6.0-canary.38
  react: 19.1.0
  react-dom: 19.1.0
  typescript: 5.9.2
Next.js Config:
  output: N/A

Which area(s) are affected? (Select all that apply)

cacheComponents, Dynamic Routes

Which stage(s) are affected? (Select all that apply)

Vercel (Deployed), Other (Deployed), next start (local)

Additional context

No response

extent analysis

TL;DR

The issue can be resolved by verifying the getStaticParams function in the cache-components-route to ensure it correctly returns an empty array for static rendering.

Guidance

  • Review the generateStaticParams function to confirm it returns an empty array as expected for static rendering.
  • Compare the behavior in development mode to production mode to identify potential environment-specific issues.
  • Check the Vercel deployment configuration to ensure it supports static rendering for the Next.js application.
  • Verify that the next version used (15.6.0-canary.38) does not have known issues with static rendering.

Example

No specific code example can be provided without modifying the original code, but ensuring the generateStaticParams function is correctly implemented is crucial.

Notes

The issue seems to be related to the difference in behavior between development and production environments, specifically with Vercel deployment. The next version and configuration might play a role in this discrepancy.

Recommendation

Apply workaround: Verify and adjust the generateStaticParams function and Vercel deployment settings to align with the expected static rendering behavior, as the issue might not be directly related to the version of next used.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING