Note #2026-07-04-001
> Reply to mauricerenck/komments
SQLite comment storage (v3) breaks page-cache invalidation (staticache): comments show in Panel but not on cached pages
Summary
Since v3 moved comment storage from inline content-file fields to SQLite, komments no longer triggers Kirby's page-cache invalidation when a comment or webmention changes. On any site that uses a page cache — in particular the official getkirby/staticache — new comments show up in the Panel (which reads the DB live) but never appear on the public page, which keeps serving stale cached HTML until the page's content file happens to be edited for some unrelated reason.
This is effectively a silent regression for anyone who paired komments with a page cache.
Root cause
-
In v2, received comments/webmentions were written into the page's content file. A content-file write is a page change, so Kirby automatically flushed that page's cache and the public page updated on the next request — invalidation came "for free" as a side effect.
-
In v3 with
storage.type => 'sqlite', comments are written to the SQLite DB and the content file is never touched. Kirby only invalidates a page's cache entry when the page/model itself changes, so nothing flushes the cache.$page->comments()reads live from the DB on render, but with a page cache active the cached HTML is served withoutrender()ever being called.
Steps to reproduce
- Kirby with page caching enabled, e.g.
getkirby/staticache(cache.pages.type => 'static'). - komments v3 with
storage.type => 'sqlite'. Webmentions auto-publish by default; comments via a moderated-then-published flow. - Visit a post once to prime the cache.
- Receive a webmention (or publish a comment) for that post.
- Panel shows the comment; the public page does not (stale cached HTML). It only corrects itself if the page's content file is later edited.
Expected
Adding, publishing, or removing a comment/webmention for a page should mark that page's cache stale, so the next request re-renders with the current comments.
What already works vs. the gaps
komments already fires hooks integrators can subscribe to for cache invalidation:
-
komments.comment.received -
komments.comment.replied -
komments.comment.published(fires on the publish/unpublish toggle, both directions)
But several mutations that change public output fire no event at all, so there is no way to invalidate on them:
-
deleteComment/deleteCommentsInBatch(moderation delete) — no trigger -
flagComment/flagCommentsInBatch(spam/flag, which can hide a comment) — no trigger
These live under the plugin's api routes, so they also can't be caught via Kirby's route:after hook (that only fires for the front-end router, not the Panel API), and there is no API-level hook. So today a delete or spam-flag can't be reliably detected by an integrator.
Suggestions (any one would help)
- Emit a complete set of mutation hooks. Add triggers for delete and flag and their batch variants — e.g.
komments.comment.deleted/komments.comment.flagged— mirroring the existingreceived/published/repliedevents. A complete event surface lets integrators reliably purge the cache for the affected page(s). - Optional built-in page-cache purge. When a comment for a page changes, remove that page's entry from
kirby()->cache('pages')(driver-agnostic — works for file, APCu, Redis, and staticache alike). Could be gated behind an option such asmauricerenck.komments.flushPageCache => true. - At minimum, document the caveat. Note in the SQLite-storage docs that DB storage no longer auto-invalidates page caches, and that integrators using a page cache must wire up invalidation via the hooks above.