Skip to content

feat(runtime): switch page cache to opt-in via PAGE_CACHE_ALLOWED_KEY - #1200

Merged
igoramf merged 1 commit into
mainfrom
feat/page-cache-opt-in
May 22, 2026
Merged

feat(runtime): switch page cache to opt-in via PAGE_CACHE_ALLOWED_KEY#1200
igoramf merged 1 commit into
mainfrom
feat/page-cache-opt-in

Conversation

@igoramf

@igoramf igoramf commented May 22, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Removes DECO_PAGE_CACHE_ENABLED env var — CDN caching no longer needs to be explicitly enabled via environment variable
  • Replaces opt-out caching model with opt-in: runtime only sets public Cache-Control when PAGE_CACHE_ALLOWED_KEY is present in the bag
  • Removes PAGE_DIRTY_KEY import/usage from the runtime middleware
  • PAGE_CACHE_ALLOWED_KEY was already defined in blocks/utils.tsx and exported from blocks/mod.ts; this PR wires it into the runtime

Context

Previously, the runtime applied Cache-Control: public, max-age=90... to all HTML responses when DECO_PAGE_CACHE_ENABLED=true, relying on apps to set PAGE_DIRTY_KEY to opt out. This had two problems:

  1. Required an env var to be set per-site to activate
  2. Any site without a middleware that explicitly marked pages dirty would get CDN caching — even if unintended

The new model requires apps to explicitly set PAGE_CACHE_ALLOWED_KEY in the bag to receive CDN cache headers. No env var needed. Apps that don't set the key are unaffected (their existing proxy/CDN behavior is preserved).

Test plan

  • VTEX site with cacheable segment → PAGE_CACHE_ALLOWED_KEY set by vtex middleware → runtime applies Cache-Control: public, max-age=90, s-maxage=90, stale-while-revalidate=3600, stale-if-error=86400
  • VTEX site with non-cacheable segment → no key set → runtime does not apply public cache headers
  • Non-VTEX site (no middleware setting the key) → runtime does not apply public cache headers
  • Response with Set-Cookie → always no-store regardless of key (existing behavior preserved)
  • Site without DECO_PAGE_CACHE_ENABLED=true in env → cache works normally (env var no longer required)

🤖 Generated with Claude Code

Replaces the opt-out model (cache unless PAGE_DIRTY_KEY is set) with an
opt-in model (cache only if PAGE_CACHE_ALLOWED_KEY is set). Apps that
do not explicitly opt in will no longer receive CDN Cache-Control headers
from the runtime, preserving their existing behavior.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

Tagging Options

Should a new tag be published when this PR is merged?

  • 👍 for Patch 1.198.1 update
  • 🎉 for Minor 1.199.0 update
  • 🚀 for Major 2.0.0 update

@coderabbitai

coderabbitai Bot commented May 22, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

The PR refactors page cache eligibility logic in middleware from using a DECO_PAGE_CACHE_ENABLED environment flag combined with dirty key checking to a runtime bag-based approach using PAGE_CACHE_ALLOWED_KEY, with imports and caching condition updated accordingly.

Changes

Page Cache Eligibility Refactoring

Layer / File(s) Summary
Cache eligibility gating logic
runtime/middleware.ts
Imports switch from PAGE_DIRTY_KEY to PAGE_CACHE_ALLOWED_KEY; the DECO_PAGE_CACHE_ENABLED constant is removed; caching condition changes from PAGE_CACHE_ENABLED && !isPageDirty to ctx.var.bag?.has(PAGE_CACHE_ALLOWED_KEY) lookup.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Possibly related PRs

  • deco-cx/deco#1136: Both PRs modify runtime/middleware.ts's HTML page-caching behavior—main PR changes the eligibility gating via PAGE_CACHE_ALLOWED_KEY, while the retrieved PR changes the Cache-Control directives (e.g., stale-while-revalidate duration) for the eligible HTML responses.
  • deco-cx/deco#1009: Both PRs modify runtime/middleware.ts to force Cache-Control: no-store, no-cache, must-revalidate when a response contains a Set-Cookie header.
  • deco-cx/deco#1095: Both PRs modify runtime/middleware.ts's HTML page-caching eligibility logic—switching/using bag-based cache gating versus dirty/cookie detection—so the caching decision code overlaps directly.

Suggested reviewers

  • guitavano
  • hugo-ccabral

Poem

🐇 Hop through the bag, no flags to chase,
Cache logic now runs at runtime's pace,
Import the key, condition's true and bright,
Page caching flows with strategic might! ✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the main change: switching from opt-out to opt-in page caching via PAGE_CACHE_ALLOWED_KEY, which directly aligns with the changeset's primary objective.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/page-cache-opt-in

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 1 file

Re-trigger cubic

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.

2 participants