Skip to content

fix(core): invalidate edge cache on settings/menu writes (#2042)#2131

Open
swissky wants to merge 2 commits into
emdash-cms:mainfrom
swissky:fix/astro-cache-invalidate-2042
Open

fix(core): invalidate edge cache on settings/menu writes (#2042)#2131
swissky wants to merge 2 commits into
emdash-cms:mainfrom
swissky:fix/astro-cache-invalidate-2042

Conversation

@swissky

@swissky swissky commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

What does this PR do?

Editing site settings or a menu never evicted rendered HTML from the Cloudflare Workers route cache. Pages went stale until their maxAge lapsed, even though the in-memory object cache was invalidated.

This PR closes the gap:

  • Adds reserved route-cache tags emdash:settings and emdash:menus plus an invalidateEdgeTag() helper (packages/core/src/astro/edge-cache-tags.ts).
  • The settings POST route and every state-changing menu route (create / update / delete / reorder / translate / item update / item delete) now purge their reserved tag on success — no-op when no cache provider is configured, same contract as the content write paths.
  • Pages that render settings or menus are tagged so the purges reach them: <EmDashHead> adds emdash:settings, and menu widgets (WidgetRenderer) add emdash:menus.
  • Sites calling getMenu() directly can opt a page into the same invalidation with Astro.cache.set({ tags: [EDGE_TAG_MENUS] }) (both tags are now exported from emdash).
  • The Cloudflare deployment docs now explain that a publish only evicts cached pages whose tags line up, and show how to tag content, menus, and settings.

Closes #2042

Type of change

  • Bug fix
  • Feature (requires maintainer-approved Discussion)
  • Refactor (no behavior change)
  • Translation
  • Documentation
  • Performance improvement
  • Tests
  • Chore (dependencies, CI, tooling)

Checklist

  • I have read CONTRIBUTING.md
  • pnpm typecheck passes
  • pnpm lint passes
  • pnpm test passes (or targeted tests for my change)
  • pnpm format has been run
  • I have added/updated tests for my changes (if applicable)
  • User-visible strings in the admin UI are wrapped for translation (if applicable). Do not include messages.po changes except in translation PRs — a workflow extracts catalogs on merge to main.
  • I have added a changeset (if this PR changes a published package)
  • New features link to an approved Discussion: https://github.com/emdash-cms/emdash/discussions/...

AI-generated code disclosure

  • This PR includes AI-generated code — model/tool: Cursor + Kimi K3

Screenshots / test output

…2042)

Editing site settings or a menu never evicted rendered HTML from the
Cloudflare Workers route cache — pages went stale until maxAge lapsed.

Settings and menu write paths now purge reserved route-cache tags
(emdash:settings, emdash:menus), and the pages that render them are
tagged so the purges reach them: EmDashHead tags emdash:settings, menu
widgets tag emdash:menus. Sites calling getMenu() directly can opt in
with Astro.cache.set({ tags: [EDGE_TAG_MENUS] }). Docs explain the
publish-vs-eviction contract.
@changeset-bot

changeset-bot Bot commented Jul 19, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: fa1d6a6

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 16 packages
Name Type
emdash Patch
@emdash-cms/cloudflare Patch
@emdash-cms/sandbox-workerd Patch
@emdash-cms/fixture-perf-site Patch
@emdash-cms/perf-demo-site Patch
@emdash-cms/cache-demo-site Patch
@emdash-cms/do-demo-site Patch
@emdash-cms/do-solo-demo-site Patch
@emdash-cms/admin Patch
@emdash-cms/auth Patch
@emdash-cms/blocks Patch
@emdash-cms/gutenberg-to-portable-text Patch
@emdash-cms/x402 Patch
create-emdash Patch
@emdash-cms/auth-atproto Patch
@emdash-cms/plugin-embeds Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@pkg-pr-new

pkg-pr-new Bot commented Jul 19, 2026

Copy link
Copy Markdown

Open in StackBlitz

@emdash-cms/admin

npm i https://pkg.pr.new/emdash-cms/emdash/@emdash-cms/admin@2131

@emdash-cms/auth

npm i https://pkg.pr.new/emdash-cms/emdash/@emdash-cms/auth@2131

@emdash-cms/auth-atproto

npm i https://pkg.pr.new/emdash-cms/emdash/@emdash-cms/auth-atproto@2131

@emdash-cms/blocks

npm i https://pkg.pr.new/emdash-cms/emdash/@emdash-cms/blocks@2131

@emdash-cms/cloudflare

npm i https://pkg.pr.new/emdash-cms/emdash/@emdash-cms/cloudflare@2131

@emdash-cms/contentful-to-portable-text

npm i https://pkg.pr.new/emdash-cms/emdash/@emdash-cms/contentful-to-portable-text@2131

emdash

npm i https://pkg.pr.new/emdash-cms/emdash@2131

create-emdash

npm i https://pkg.pr.new/emdash-cms/emdash/create-emdash@2131

@emdash-cms/gutenberg-to-portable-text

npm i https://pkg.pr.new/emdash-cms/emdash/@emdash-cms/gutenberg-to-portable-text@2131

@emdash-cms/plugin-cli

npm i https://pkg.pr.new/emdash-cms/emdash/@emdash-cms/plugin-cli@2131

@emdash-cms/plugin-types

npm i https://pkg.pr.new/emdash-cms/emdash/@emdash-cms/plugin-types@2131

@emdash-cms/registry-client

npm i https://pkg.pr.new/emdash-cms/emdash/@emdash-cms/registry-client@2131

@emdash-cms/registry-lexicons

npm i https://pkg.pr.new/emdash-cms/emdash/@emdash-cms/registry-lexicons@2131

@emdash-cms/registry-verification

npm i https://pkg.pr.new/emdash-cms/emdash/@emdash-cms/registry-verification@2131

@emdash-cms/sandbox-workerd

npm i https://pkg.pr.new/emdash-cms/emdash/@emdash-cms/sandbox-workerd@2131

@emdash-cms/x402

npm i https://pkg.pr.new/emdash-cms/emdash/@emdash-cms/x402@2131

@emdash-cms/plugin-ai-moderation

npm i https://pkg.pr.new/emdash-cms/emdash/@emdash-cms/plugin-ai-moderation@2131

@emdash-cms/plugin-atproto

npm i https://pkg.pr.new/emdash-cms/emdash/@emdash-cms/plugin-atproto@2131

@emdash-cms/plugin-audit-log

npm i https://pkg.pr.new/emdash-cms/emdash/@emdash-cms/plugin-audit-log@2131

@emdash-cms/plugin-color

npm i https://pkg.pr.new/emdash-cms/emdash/@emdash-cms/plugin-color@2131

@emdash-cms/plugin-embeds

npm i https://pkg.pr.new/emdash-cms/emdash/@emdash-cms/plugin-embeds@2131

@emdash-cms/plugin-field-kit

npm i https://pkg.pr.new/emdash-cms/emdash/@emdash-cms/plugin-field-kit@2131

@emdash-cms/plugin-forms

npm i https://pkg.pr.new/emdash-cms/emdash/@emdash-cms/plugin-forms@2131

@emdash-cms/plugin-webhook-notifier

npm i https://pkg.pr.new/emdash-cms/emdash/@emdash-cms/plugin-webhook-notifier@2131

commit: fa1d6a6

@ascorbic ascorbic left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I think middleware is probably the best place to set these

// This page renders site settings, so it must be evicted when they change.
// Tag it with the reserved settings tag so the settings write path's purge
// reaches it (#2042). Merges with any tags the route already set.
Astro.cache.set({ tags: [EDGE_TAG_SETTINGS] });

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This is risky to put inside a component, because depending on how it's used, there's a chance the headers will have already been sent.

@github-actions github-actions Bot added review/awaiting-author Reviewed; waiting on the author to respond and removed review/needs-review No maintainer or bot review yet labels Jul 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Publishing content does not invalidate the Astro cache provider — edge-cached HTML stays stale for the full TTL

2 participants