Skip to content

View Model Cache Tags for Proper Cache Invalidation

Hyvä extends Magento's cache tag system to support page cache tags via view models, solving a critical limitation in Magento's architecture. When view models provide data that indicate a page should be flushed during cache invalidation triggers (such as product or category data), Hyvä automatically collects the cache tags and adds them to both FPC and Block HTML cache records.

This document explains how to implement cache tags in view models and how Hyvä's ViewModelRegistry handles cache tag collection. Familiarity with Magento Block HTML and Full Page Caching is recommended.

The Problem: View Models Cannot Contribute Cache Tags

Hyvä themes use View Models extensively to provide data to templates. Templates access view models through the Hyvä ViewModelRegistry:

/** @var \Hyva\Theme\Model\ViewModelRegistry $viewModels */
$productPriceViewModel = $viewModels->require(\Hyva\Theme\ViewModel\ProductPrice::class);

Standard Magento provides no mechanism for view models to add cache tags to page responses. This means pages using view models may not invalidate properly when underlying data changes.

Hyvä's Solution: IdentityInterface for View Models

Hyvä's ViewModelRegistry enables view models to contribute cache tags by implementing Magento\Framework\DataObject\IdentityInterface—the same interface blocks use for FPC cache tags.

Example: View Model with Cache Tags

The following example shows a view model that returns the current product's cache tags. When this view model is used on a page, any cache entries will be invalidated when the product is modified:

class CurrentProduct implements
    ArgumentInterface,
    \Magento\Framework\DataObject\IdentityInterface
{
    // ...

    public function getIdentities(): array
    {
        // Delegate to the product's own cache tags if it implements IdentityInterface
        return $this->currentProduct instanceof IdentityInterface
            ? $this->currentProduct->getIdentities()
            : [];
    }
}

Automatic Cache Tag Collection

When a template calls $viewModels->require(), the ViewModelRegistry checks if the view model implements IdentityInterface. If so, the view model's getIdentities() return values are automatically added to the page response's X-Magento-Tags header for FPC invalidation, and to Block HTML cache records.

Technical Implementation Details

Internal Documentation

The following content documents Hyvä's internal implementation. Understanding these details is not required to use view model cache tags—simply implement IdentityInterface on your view models.

How ViewModelRegistry Collects Cache Tags

When ViewModelRegistry::require() instantiates a view model, it calls Hyva\Theme\Model\ViewModelCacheTags::collectFrom($viewModel) to register view models that implement IdentityInterface.

The ViewModelCacheTags class stores references to these view models and provides a get() method to retrieve all collected cache tags.

Lazy Evaluation of getIdentities()

Cache tags are collected lazily—getIdentities() is not called until the response is being finalized. This is important because some view models accumulate data during rendering.

For example, the Navigation view model builds its cache tags as it traverses the category tree during menu rendering. Calling getIdentities() too early would miss categories loaded later in the render process.

Supported Cache Configurations

The view model cache tag system works correctly in all cache configurations:

  • FPC only (Varnish or built-in)
  • Block HTML cache only
  • Both FPC and Block HTML cache enabled simultaneously

Adding Tags to Page Responses

For standard page requests, Hyvä injects Hyva\Theme\Block\ViewModelCacheTagsBlock into every page via the before.body.end container in the hyva_default layout handle.

This block renders no visible output but implements IdentityInterface. When Magento collects block identities for the X-Magento-Tags response header, it calls getIdentities() on this block, which returns all cache tags collected from view models during page rendering.

Debugging Cache Tags

In developer mode, ViewModelCacheTagsBlock renders an HTML comment listing all view model cache tags, useful for verifying correct cache tag propagation.

Adding Tags to ESI Responses

ESI (Edge Side Includes) requests require special handling because the content may be served from Block HTML cache without instantiating view models.

ESI Without Block HTML Cache

When ESI content is not also cached in Block HTML cache, cache tags are added normally—view models are instantiated, and their cache tags are collected and added to the ESI response headers.

ESI With Block HTML Cache (Double-Cached Blocks)

When content is cached in both ESI and Block HTML cache (like the navigation menu), the Block HTML cache serves the response directly without instantiating view models. This means no view model cache tags would be included in the ESI response.

Hyvä solves this with a two-part mechanism:

  1. Tag Storage: A plugin on Layout::getOutput() identifies blocks cached in both the ESI and Block HTMl cache and stores their view model cache tags in a separate Block HTML cache record
  2. Tag Retrieval: The plugin Hyva\Theme\Plugin\PageCache\AddViewModelCacheTagesToEsiResponse on Magento\PageCache\Controller\Block\Esi retrieves the stored cache tags and adds them to the ESI response's X-Magento-Tags header

This ensures proper cache invalidation even when ESI content is served from Block HTML cache.