Contao native frontend cache or Symfony HTTP cache for shared-content invalidation
0 reputation · 07 Apr 2021, 10:09 UTC
0 reputation · 07 Apr 2021, 10:09 UTC
Goal: Keep anonymous visitor HTML current when a shared content element, such as a navigation item or news teaser, is edited in the Contao backend and displayed on multiple pages.
Constraint: Contao's native frontend cache clears the originating page on save but may not invalidate every dependent page. An external Symfony HTTP cache or Varnish proxy requires separate purge keys and does not automatically receive Contao's backend cache-clearing signals. Behavior can differ between Contao 4.x LTS and 5.x depending on installed extensions.
34775 reputation · 07 Apr 2021, 19:45 UTC
When a content element (e.g., a navigation module or a news teaser) is rendered on several pages, the safest guarantee comes from an explicit, URL‑ or tag‑based purge that the element’s save event triggers. Contao’s built‑in page cache is page‑oriented and only knows about the page that was edited; it has no general dependency graph for arbitrary shared modules. Therefore, for multi‑page reuse, an external reverse proxy (Symfony HttpCache or Varnish) with a custom invalidation hook is usually the more reliable choice, provided the bridge is correctly implemented.
Contao’s native frontend cache clears the edited page and, if it can resolve dependencies, any pages that reference that element. The resolution logic is limited to core cache‑clearing hooks and the extensions installed. In Contao 4.x LTS it only clears the edited page and a handful of obvious dependents; in Contao 5.x the logic has been extended but still depends on the exact extension set. Because the behavior is not guaranteed across all versions, you should verify the list of URLs that are cleared after an edit in your own environment.
/purge route is protected by a CSRF token or a shared secret. For Varnish, use the PURGE method or a BAN header.config/contao/config.php add:
\Contao\System::getContainer()->get('contao.framework')->get('contao.framework')->registerHook('savePage', ['Contao\MyModule\CachePurger', 'onSave']);
onSave, inspect the changed element’s id and query the database for all pages that include it. Store the resulting URLs in an array.$client = new \GuzzleHttp\Client();
foreach ($urls as $url) {
$client->request('PURGE', $url, [
'headers' => ['X-Contao-Secret' => $secret]
]);
}
With this bridge, every time the shared element is edited, all pages that render it are explicitly invalidated in the proxy, ensuring anonymous visitors always receive fresh HTML.
To decide whether the above hook is sufficient, we need to know what type of element is being shared:
tl_content module)Different element types may require different database queries for the dependency list. Please confirm the element type so the hook can be tailored accordingly.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.