stoffel.io

Statamic Tip: Invalidating Static Cache on Content Update

Static caching gives your site a speed boost, but it can also lead to some confusing output and bugs. Sometimes the changes you made to your content don't show up on the public pages at all, and sometimes they show up in some areas but not in others.

When you edit the content of a single page or post, that page is usually flushed from the cache (although this is a bit buggy at the time of this post) - meaning someone reading your updated blog post will see the newest version.

But Statamic doesn't know your page structure and it doesn't check every single site to see if that blog post maybe also appears on those. So while the post itself will be updated for your visitors, the list of posts or your front page might still be showing outdated information.

This can be annoying - both for the reader who clicked on one headline and is then presented with a differently titled post, and for the backend user who might be wondering what's they're doing wrong.

So how can we fix this so we keep our content consistent even with static caching?

Manually clearing the cache

You could simply go to the Cache Manager under Utilities in the Control Panel and empty the Static Page Cache with the click of a button. Or you can SSH into your server and run the command php please static:clear, or even manually delete or empty the static caching folder (usually public/static).

While this does the trick, it's not exactly handy. You'll have to do this for every content change and it's very easy to forget and end up with outdated content being served to your users.

Needless to say it's also not very user friendly if you're developing a Statamic site for somebody else. You will most likely receive a lot of support tickets about broken pages when the client only forgot to empty the cache.

Cache Timeout

If you are using the half strategy, you have another option at your disposal: a time limit. By setting in expiry your caching strategy definition, the cache will automatically be refreshed after the limit is over.

config/statamic/static_caching.php (excerpt)
return [ 'strategy' => 'half', 'strategies' => [ 'half' => [ 'driver' => 'application', 'expiry' => 60, ] ] ];
The cache is set to expire automatically every hour (60 minutes)

While there might be certain cases where this is helpful, most websites aren't updated in regular intervals. So by using the cache timeout you both delay publishing your content and also waste resources by doing cache refreshes when nothing has changed.

Invalidating Cache on Change

So instead the goal is to update the site only when content changes, and then clear exactly those pages from the cache that may use the data that was changed.

And of course Statamic offers a solution for this as well, although it's hidden in the config files. By defining invalidation rules you can define which urls should be flushed from the cache when any of your content changes.

You can define different rules for each collection, global, taxonomy, and navigation - see the documentation for details.

config/statamic/static_caching.php (excerpt)
return [ 'invalidation' => [ 'rules' => [ 'collections' => [ 'posts' => [ 'urls' => [ '/', '/blog' ] ] ], 'globals' => [ 'footer' => [ 'urls' => [ '/*' ] ] ] ] ] ];
Examples for static caching invalidation rules

In this example we have only two rules, which is enough for a small site like mine.

First I'm targeting the posts collection to invalidate other content when I publish or edit a blog post. In this case I want to also update the front page and the blog overview page, since both might show the headline or excerpt of the post in question.

Next I have a globals container named footer which contains - surprise, surprise - everything you can see in my page footer. The footer is displayed on every single page, so in this case I use the wild card selector '/*' to clear the entire static site cache.

So you can use static caching and still keep your site up to date with changes. All it takes is a good overview of what content is used on which pages and a few lines of code.

More posts: