Skip to content

fix(preview): stop caching the embedding verdict indefinitely#2012

Merged
markdumay merged 2 commits into
mainfrom
fix/stale-preview-cache
Jul 13, 2026
Merged

fix(preview): stop caching the embedding verdict indefinitely#2012
markdumay merged 2 commits into
mainfrom
fix/stale-preview-cache

Conversation

@markdumay

Copy link
Copy Markdown
Collaborator

Problem

Hugo caches remote resources forever by default (caches.getresource maxAge = -1), and
netlify-plugin-hugo-cache-resources carries that cache from build to build.

The preview component reads a target's response headers to decide whether it can be embedded — so a
stale cache entry pins the verdict to whatever the target sent the first time it was fetched.
Correcting a target's CSP then has no effect on a rebuild.

This is not a theoretical risk. After gethinode/gethinode.com#154, #2008 and
gethinode/theme-agency#384 all merged and deployed, the Agency and Hinode (classic)
showcases stayed on their fallback screenshots, even though:

  • demo.gethinode.com and theme-agency.gethinode.com now send frame-ancestors 'self' gethinode.com
  • gethinode.com's frame-src allows them
  • gethinode.com had since rebuilt (the mod-leaflet bump went live in that same build)

The rebuild re-read the old headers out of the cache. Recovering requires a cache-cleared deploy,
and nothing in the build output says so — it just silently keeps showing screenshots.

Change

Cap the lifetime of the remote-resource cache:

[caches]
  [caches.getresource]
    maxAge = "5m"

Builds are further apart than five minutes, so headers are re-read on every build, while a single
build still fetches each one only once. getresource also backs remote images (mod-utils) and video
posters (hinode), so the cache is shortened rather than disabled — those are re-fetched per build,
not per use.

Also upgrades mod-leaflet to v3.1.0 (gethinode/mod-leaflet#266), which gives the map cooperative
gestures. The map on /docs/components/map trapped page scroll until now; gethinode.com already has
this bump, the demo did not.

Verification

Built the exampleSite with the new module vendored:

  • Hugo parses the cache setting: [caches.getresource] maxage = '5m0s'.
  • The demo's map page carries the gesture wiring (data-leaflet-hint-zoom, data-leaflet-hint-drag),
    and the overlay styles compile into the leaflet CSS bundle.
  • mod-leaflet ships an i18n mount for the first time, so I checked it resolves: a Dutch page renders
    "Gebruik twee vingers om de kaart te verplaatsen".
  • netlify.toml is unchanged — neither change affects the published headers.

Note: the module bump only takes effect after pnpm mod:vendor; a stale _vendor/ silently
shadows it (hugo mod graph showed mod-leaflet@v3.0.0+vendor until I re-vendored). Netlify
re-vendors on every build, so this only bites locally.

🤖 Generated with Claude Code

Hugo caches remote resources forever by default (caches.getresource maxAge -1), and the Netlify
cache plugin carries that cache from build to build. The preview component reads a target's
response headers to decide whether it can be embedded, so a stale entry pins the verdict to
whatever the target sent the first time it was fetched.

That is not hypothetical: the showcase previews on gethinode.com stayed on their fallback
screenshots after both sides of the embed were corrected and the site was rebuilt, because the
build re-read the old headers out of the cache. Recovering needs a cache-cleared deploy, and
nothing in the build says so.

Cap the lifetime at 5 minutes. Builds are further apart than that, so the headers are re-read on
every build, while a single build still fetches each one only once.

Also upgrade mod-leaflet to v3.1.0, which gives the map cooperative gestures: the map on
/docs/components/map trapped page scroll until now.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@netlify

netlify Bot commented Jul 13, 2026

Copy link
Copy Markdown

Deploy Preview for gethinode-demo ready!

Name Link
🔨 Latest commit d63fdd9
🔍 Latest deploy log https://app.netlify.com/projects/gethinode-demo/deploys/6a54f863476b5200089ce742
😎 Deploy Preview https://deploy-preview-2012--gethinode-demo.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

v1.15.1 documents the cooperative gestures that mod-leaflet v3.1.0 introduces, so the demo's map
page describes the behaviour it now has rather than the behaviour it used to have.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@markdumay

Copy link
Copy Markdown
Collaborator Author

Added: mod-docs v1.15.1

Bumped mod-docs to v1.15.1, which documents the cooperative gestures that mod-leaflet v3.1.0
introduced — so the demo's map page describes the behaviour it now has, not the behaviour it used
to have.

The documentation change (gethinode/mod-docs#115) had merged without a release: docs: is not a
releasable commit type under the default semantic-release rules, so a dispatch of the Release
workflow reported Analysis of 5 commits complete: no release. The content was already on main,
so v1.15.1 was published as a tag.

Verified on the exampleSite build: the map page now documents the gestures, and netlify.toml is
unchanged.

@markdumay markdumay enabled auto-merge July 13, 2026 14:42
@markdumay markdumay merged commit 8d23f9c into main Jul 13, 2026
16 checks passed
@markdumay

Copy link
Copy Markdown
Collaborator Author

🎉 This PR is included in version 3.0.3 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

@markdumay markdumay deleted the fix/stale-preview-cache branch July 13, 2026 14:47
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.

1 participant