Installation
Install, model an index, build and publish. After that it maintains itself.
Requirements
- Craft CMS 5.3 or later
- PHP 8.2 or later
No runtime dependencies beyond Craft itself. The browser runtime ships as ES modules with no build step, so there is nothing to compile and nothing in your bundle.
Install
composer require justinholtweb/craft-caffeine
php craft plugin/install caffeine
Or install it from the Plugin Store, which is also where the Pro licence lives.
Define an index
Go to Caffeine → Indexes and create one. At minimum it needs a source — where records come from — and one attribute. See Defining an index for what each part does.
Before you build anything, use the record preview on the edit screen: give it the ID of one real element and it shows exactly what the mapper produces, including which elements the record now depends on. It is much faster than rebuilding and reading the artifact, and it is where a mistyped field handle shows up.
Build and publish
# map your content into records
php craft caffeine/index/build --all
# compile those records into an artifact and publish it
php craft caffeine/artifact/publish
Those are two steps rather than one because they are genuinely separate operations: records are rebuilt whenever content changes, and an artifact is cut when that should become visible. A deploy script usually wants them at different moments.
Check it
# what is live, and whether it is behind the CMS
php craft caffeine/artifact/status
# read the published artifact back and compare it to a fresh compile
php craft caffeine/artifact/verify products
Put it on a page
{% caffeine 'products' as search %}
{{ search.searchBox() }}
{{ search.refinementList('brand') }}
{% caffeineresults %}
{% for hit in search.hits %}
<li>{{ hit.title }}</li>
{% endfor %}
{% endcaffeineresults %}
{% endcaffeine %}
After that
Element saves mark the affected records stale and a debounced queue job rebuilds and republishes. A resave across thousands of entries collapses to one job rather than thousands. Nothing else is required.
If your queue does not run, the index simply stays as it was — the previously published artifact keeps being served. Nothing breaks; it just stops being fresh.