Skip to content

Disabling the page cache for logged-in users

Customize pages for authenticated users while using the default page cache.

Using Kirby's page cache is an efficient means to improve the performance of a website. It keeps a copy of every page rendered and Kirby returns the cached copy for future requests instead of rendering it anew.

Sometimes, it may come handy to bypass the cache for logged-in users.

Using the page cache

As a built-in default, the page cache is enabled with the cache.pages option in config.php:

/site/config/config.php
return [
    'cache' => [
        'pages' => [
            'active' => true
        ]
    ]
];

Kirby also takes care of emptying the cache whenever content is changed through the Panel so that no outdated content is served to users.

The reason for emptying the entire cache is that content often is referenced elsewhere, hence it is safest to always start fresh.

Reasons for selective caching

Sometimes, it may be desired to use the page cache only for users that are not logged in: anonymous users receive pre-rendered copies from the cache, while pages are still rendered live for authenticated users.

Possible use cases for such setup could be:

  • revealing exclusive content to logged-in users
  • showing additional items in a navigation
  • displaying an "Edit" button on pages for logged-in editors
  • advanced features for site admins, not intended for public eyes

Using the default setup for the page cache is not feasible in this case. Since the cache always keeps a copy of the first render after its last reset, the cache could end up containing a mix of renderings of the public and the private version of the website. Apart from the inconsistencies, we of course would not want any of those private views to leak to the outside.

Disabling the cache for logged-in users

While it may appear obvious to replace 'active' => true with 'active' => !kirby()->user() (returning a boolean depending on whether a user session is active or not), this does not work, as $kirby is not yet available when the configuration settings are parsed.

It would be possible to move the test for a logged-in user into the ready option, executed after Kirby is completely initiated, but another problem emerges with modifying the active setting:

Since API calls (most importantly used by the Panel) always originate from authenticated users, this setting would disable the cache for such request; yet, as that would make Kirby believe the cache to be disabled globally when processing authenticated requests, it would not empty the page cache when content is updated.

Therefore, the most straightforward way to achieve this is by moving the test for a user session into the ignore callback:

/site/config/config.php
<?php
return [
    'cache' => [
        'pages' => [
            'active' => true,
            'ignore' => function() {
                return kirby()->user() !== null;
            }
        ]
    ]
];

This function is executed later, when $kirby is available; therefore even eliminating the need to use the ready option. At the same time, we keep caching active globally to ensure the cache is reset whenever content is being edited and only return an ignore boolean as Kirby responds to frontend requests from logged-in users.

Disable for one user only

On some sites (e.g. scenarios with user accounts for readers), it may be useful to narrow this down even further. To disable the page cache for one specific user only, the according line in the code can be replaced with:

return kirby()->user() !== null && kirby()->user()->email() === 'name@example.com';

Similarly, we can test for a group of users by their role, for example a team of content editors that we want to see a custom "Edit" button in the template:

return kirby()->user() !== null && kirby()->user()->role()->id() === 'editor';

Advanced conditional rules

Since the ignore value of the page cache setting is initially designed to exclude certain pages from being cached, this can of course be integrated with above approach.

To replicate the example from the documentation (disabling the cache for any pages with title "Do not cache me") this condition would have to be combined with the test for a user session using an AND operator:

/site/config/config.php
<?php
return [
    'cache' => [
        'pages' => [
            'active' => true,
            'ignore' => function($page) {
                return kirby()->user() !== null && $page->title()->value() === 'Do not cache me';
            }
        ]
    ]
];

This can be extended by further conditions, all of which should return true for those cases where the cache should be bypassed.

Author

This cookbook recipe was written by Sebastian Greger.