Blitz 4.3 has been released and it packs some important features including a dashboard widget, new include functions with SSI and ESI support, as well as a PHP equivalent of server rewrites. In this article we’ll run through when and why you might want to use each of them.

Blitz dashboard widget

Dashboard Widget #

The new Blitz Cache dashboard widget contains the ability to refresh specific URIs, all pages in a site, or the entire cache. Its user interface is much more focused and approachable than the Blitz Cache utility, which contains more functionality than most users will ever need.

Blitz dashboard widget

Include Functions #

Blitz 4.3 adds new include functions, alongside support for Server-Side Includes (SSI) and Edge-Side Includes (ESI).

These features are a result of a Twitter poll we conducted in 2022. After exploring the pain points and reasoning for why people wanted partial template caching”, we realised they could be solved with include functions combined with SSI or ESI

Twitter poll Blitz

craft.blitz.includeCached() #

This function is useful for including a cached template, especially when your server supports SSI or ESI. It works similarly to the regular include() function except that it is loaded via a Server-Side Include or an Edge-Side Include if enabled via the new advanced settings.

{{ craft.blitz.includeCached('path/to/template', params) }}

The reason you might want to use this is that the included template will be cached as its own entity. If multiple pages use the cached include, and it outputs one or more elements, then any time those elements are updated, only the cached include will need to be regenerated.

For example, imagine your site contains mutliple pages, all of which output a button containing a call-to-action entry (or a nav bar, sidebar or footer containing entries). 

{% set ctaEntry = craft.entries.slug('call-to-action').one() %}
<button>
    {{ ctaEntry.title }}
</button>
No includes
Each cached page must keep track of the call-to-action entry.

Now any time the call-to-action entry is updated, Blitz needs to regenerate the cache for all pages that reference it. 

However, if we use the includeCached function, Blitz only needs to refresh one cached include, because all the other pages get their cached content included at request time.

{{ craft.blitz.includeCached('_includes/call-to-action') }}
Static includes
Only the cached include must keep track of the call-to-action entry. Cached includes are fast, as indicated by the hare.

For this to work with cached pages, at least one of SSI or ESI must be enabled, using the new advanced settings, as well as on the web server. If neither SSI nor ESI is enabled, Blitz will fall back to using an AJAX request, which may be desirable in some cases. 

Server-Side Includes can be enabled on Apache as follows.

#- Enable Server-Side Includes
#- https://httpd.apache.org/docs/current/howto/ssi.html
Options +Includes
AddOutputFilter INCLUDES .html .php

Server-Side Includes can be enabled on Nginx as follows.

#- Enable Server-Side Includes
#- https://nginx.org/en/docs/http/ngx_http_ssi_module.html
ssi on;

This will result in an SSI tag being output in the cached page, with the include rendered in the final HTML document that the browser receives.

<!--#include virtual="/_includes?action=blitz%2Finclude%2Fcached&index=12345" -->

craft.blitz.includeDynamic() #

This function is useful for including a dynamic template – one whose content is never cached but is dynamically rendered by Twig each time it’s called. It returns a script that injects the contents of the template via AJAX and replaces the now deprecated craft.blitz.getTemplate() function.

{{ craft.blitz.includeDynamic('path/to/template', params) }}

A third options parameter can be passed into the function. Once common example is to add placeholder content that will be displayed until the result is swapped in.

{% set options = { placeholder: '<img src="/images/placeholder.svg">' } %}
{{ craft.blitz.includeDynamic('path/to/template', params, options) }}
Dynamic includes
The included template is dynamically rendered each time the page loads. Dynamic includes are not particularly fast, as indicated by the tortoise (walking in the wrong direction).

craft.blitz.fetchUri() #

This function is useful for fetching the contents of a URI – one whose output may or may not be cached, depending on the included and excluded URI pattern settings. It returns a script that injects the contents of the URI via AJAX and replaces the now deprecated craft.blitz.getUri() function.

{% set options = { placeholder: '<img src="/images/placeholder.svg">' } %}
{{ craft.blitz.fetchUri(uri, params, options) }}

Note that while passing parameters into all of the functions above is possible, the values will be sent as query string parameters. Therefore, only primitive data types should be used: strings, numbers, booleans and arrays. Objects, models and elements should not passed in. If you want to pass an element (or set of elements) into an include, then you should pass in an ID (or array of IDs) instead and then fetch the element from within the template.

{# Don’t pass an element in as a parameter! #}
{% set ctaEntry = craft.entries.id(10).one() %}
{{ craft.blitz.includeCached('_includes/call-to-action', { entry: ctaEntry }) }}

{# Pass in the element ID instead. #}
{{ craft.blitz.includeCached('_includes/call-to-action', { entryId: 10 }) }}

PHP Rewrites #

Server rewrites are the fastest way to serve your site using Blitz, as observed in the Performance Testing Craft CMS with Blitz article (be sure to read it if you haven’t yet!). Your web host might not allow you to configure your servers, or you might simply prefer not to do any server configuration. For those situations, it is now possible to get the benefit of rewrites using the new rewrite.php file that ships with Blitz.

Use it by requiring rewrite.php inside the web/index.php file (in the public web folder), directly after bootstrap.php is required.

// Load shared bootstrap
require dirname(__DIR__) . '/bootstrap.php';

// Load Blitz rewrite
require CRAFT_VENDOR_PATH . '/putyourlightson/craft-blitz/src/rewrite.php';

This rewrite happens via PHP, however it can still result in significant performance improvements, as observed in the PHP File” versus Early Craft Response” test results in the Load Testing Craft CMS article.

You can configure the rewrite by defining one or more constants. For example, if the Query String Caching setting is set to Cache URLs with query strings as the same page, then set BLITZ_INCLUDE_QUERY_STRING to false.

// Load Blitz rewrite without query strings and with a custom cache folder path
define('BLITZ_INCLUDE_QUERY_STRING', false);
define('BLITZ_CACHE_FOLDER_PATH', 'path/to/cache');
require CRAFT_VENDOR_PATH . '/putyourlightson/craft-blitz/src/rewrite.php';