Creating a Separate Cache Page/Block Based on Any Flag Data on Magento

7 minutes read
Creating a Separate Cache Page/Block Based on Any Flag Data on Magento
Table of Contents
Key Takeaways
  • Cache contexts are used by Magento to deliver different content to different users.
  • Using custom flags ensures that you can create separate cache entries without harming site speed.
  • Extending Http\Context helps with adding your own dynamic caching conditions.
  • You can control content variations by modifying block cache keys.
  • For highly personalized data like welcome messages or personal dashboards, use private content.
  • To ensure optimal performance after making changes, track the cache hit/miss rates.

Magento’s caching system comes with a trade-off. While it ensures unmatched store performance by serving pre-rendered blocks or pages, merchants have to face complexities when it comes to displaying different content to different users based on dynamic conditions. For example, displaying special offers only to affiliates or modifying the homepage banner based on the user’s location or device becomes a tad complex!

This is where Magento’s cache contexts and custom HTTP flags shine. In this blog, we’ll go through the step-by-step process of creating separate cacheable blocks or pages for any flag data. By the end of this blog, you’ll be all ready to deliver personalized shopping experiences with optimal store performance.

Understanding Magento Cache Context

First, let’s explore how Magento’s caching system uses Varnish tags, keys, and contexts to effectively serve and nullify cached content.

How Magento Caches Blocks/Pages Using cache_contexts, cache_keys, and Varnish Tags

The block and page caches of Magento revolve around these three concepts:

  • cache_contexts
  • Cache_contexts are called “dimensions” (currency, store view, customer group, etc.), tracked by Magento to determine cache variations. When you define a context, you instruct Magento to treat the cache as different when there’s a change in context value.
  • cache_keys
  • Magento combines different context values with block-specific identifiers to generate a composite key internally. Then it uses MD5 to hash this array, which helps create a unique string. This key identifies the unique version of the page or block, leading to precise cache retrieval.
  • Varnish tags
  • Whether served through Varnish or stored in Redis, each cached blob gets tagged (for example, catalog_product_42). When a user makes an update to related content (like saving a product), Magento triggers a purge on that corresponding tag to invalidate the outdated cache entries and serve the fresh content.

Every page or block is able to define the contexts it depends on by implementing getIdentities() and getCacheKeyInfo() within the block class.

Role of layout.xml, Block Classes, and Plugins

  • layout.xml
  • The <block> node’s cacheable=”true” attribute (which is the default for the majority of structural blocks) signals Magento that the block is eligible for caching. You can also specify a cache lifetime by using the following to control its behavior further:
  •  <arguments><argument name=”cache_lifetime” xsi:type=”number”>3600</argument></arguments>.
  • Block classes
  • Cache behavior is driven by two methods:
    • getCacheKeyInfo() returns an array of values (contexts + extra bits) to create cache_key.
    • getIdentities() returns tags for invalidation.
  • Plugins and Observers
  • If you want to add or override the context values at runtime, a plugin needs to be registered on
    \Magento\Framework\App\Http\Context::getValue(). You can also listen to an event to tweak the context bag prior to key generation.

    For a deeper dive into Magento’s layout system, check out our detailed Magento 2 Layout Overview.

Use Cases

There are various scenarios where you must vary the cache depending on dynamic flags.

Showing Different Content for Logged-in vs Guest

For this, you can use Magento’s built-in customer_logged_in context.

  1. In your block’s getCacheKeyInfo(), add the following:

$this->httpContext->getValue(\Magento\Customer\Model\Context::CONTEXT_AUTH);

  1. This will ensure that the guest shoppers see a general view while the logged-in users get a personalized feed, with both of them cached separately.

Switching Banners or Blocks According to User Location, Device, or Custom Flags

  • Location (GeoIP)
  • Integrate a GeoIP lookup service like MaxMind or other third-party modules to identify user location. Then you can expose a custom context key like user_country. Now, you can put this in your block:

$this->httpContext->getValue(‘user_country’);

This will make sure that customized promos are displayed without hitting the database on each page load.

  • Device (Mobile vs Desktop)
  • Inspect the User-Agent via a plugin on Http\Context or leverage Magento’s built-in design/theme. Expose a custom is_mobile boolean context, which can replace heavy desktop carousels with lightweight mobile sliders.
  • Custom Flags (e.g., is_affiliate_user)
  • Let’s say you want to display a “Welcome, Partner!” widget to affiliates. For that, you need to define and populate an is_affiliate_user flag in customer metadata or session, and add it to your cache keys in order to separately cache your affiliate pages from non-affiliate users.

Implementing Flag-Based Cache Variants

Here’s how you can implement the flag-based cache variants.

Step 1: Create Custom Context Class

To inform Magento about your new flag, extend the HTTP context:

<?php
namespace Vendor\Module\Plugin;
 
use Magento\Framework\App\Http\Context;
use Magento\Customer\Model\Session;
 
class AffiliateHttpContext
{
	const CONTEXT_AFFILIATE = 'is_affiliate_user';
 
	/**
 	* @var Session
 	*/
	private $customerSession;
 
	/**
 	* Constructor to inject Magento's Customer Session
 	*
 	* @param Session $customerSession
 	*/
	public function __construct(Session $customerSession)
	{
        $this->customerSession = $customerSession;
	}
 
	/**
 	* After plugin for getValue: injects our affiliate flag.
 	*
 	* @param Context $subject
 	* @param mixed   $result
 	* @param string  $key
 	* @param mixed   $default
 	* @return mixed
 	*/
	public function afterGetValue(Context $subject, $result, $key, $default = null)
	{
    	if ($key === self::CONTEXT_AFFILIATE) {
        	return $this->detectAffiliate();
    	}
    	return $result;
	}
 
	/**
 	* Determines affiliate status from Magento session.
 	*
 	* @return bool
 	*/
	private function detectAffiliate(): bool
	{
    	return (bool) $this->customerSession->getIsAffiliateUser();
	}
}

Step 2: Register Your Plugin in di.xml

<type name="Magento\Framework\App\Http\Context">
    <plugin
        name="affiliate_http_context"
        type="Vendor\Module\Plugin\AffiliateHttpContext"
        sortOrder="10"
        disabled="false" />
</type>

After this, any call to $httpContext->getValue(‘is_affiliate_user’) will return a reliable boolean. Also, it will become part of all cache keys wherever you reference it.

Modify Cache Keys in Blocks

Now, it’s time to wire the new context value into a block’s cache key. It makes sure that there are distinct cache buckets for every flag.

<?php
namespace Vendor\Module\Block;

use Magento\Framework\View\Element\Template;
use Magento\Framework\App\Http\Context as HttpContext;

class AffiliateBanner extends Template
{
    private HttpContext $httpContext;

    public function __construct(
        Template\Context $context,
        HttpContext $httpContext,
        array $data = []
    ) {
        parent::__construct($context, $data);
        $this->httpContext = $httpContext;
    }

    /**
     * Add affiliate flag to cache key info.
     *
     * @return array
     */
    public function getCacheKeyInfo(): array
    {
        return array_merge(
            parent::getCacheKeyInfo(),
            [
                'AFFILIATE_BANNER',
                (int) $this->httpContext->getValue('is_affiliate_user')
            ]
        );
    }

    /**
     * Define cache lifetime (optional, defaults to config).
     *
     * @return int|bool
     */
    public function getCacheLifetime()
    {
        return 3600; // one hour
    }
}

Why it works:

  • parent::getCacheKeyInfo() pulls in details like customer group, theme, store, etc.
  • We track on our custom AFFILIATE_BANNER tag and a 0/1 value.
  • Magento generates an MD5 hash, which creates two separate cache entries: one for affiliates and another for other users.

Using Private Content Where Needed

Not all dynamic content works well with full-page caching. Sometimes, you need to use JavaScript.

When the Block Must Be Private

There are some blocks that should never be cached and shared across users:

  • Mini-cart totals (vary per session)
  • Personalized greetings (“Hi, Davis!”)
  • Real-time stock status

Instead of using PHP, load these using the customer-data JavaScript module.

Fallback to JS-Based Rendering

  1. Define a RequireJS component in requirejs-config.js:
var config = {
    map: {
        '*': {
            'AffiliateWidget': 'Vendor_Module/js/affiliate-widget'
        }
    }
};
  1. JS module (affiliate-widget.js):
define(['jquery', 'Magento_Customer/js/customer-data'], function ($, customerData) {
    'use strict';
    return function(config) {
        var section = customerData.get('affiliate-section');
        section.subscribe(function(data) {
            if (data.isAffiliate) {
                $('#affiliate-banner').show();
            }
        });
    };
});
  1. Server-side: Add affiliate-section data in a block that is already labeled as private.
$customerData->setSectionData(‘affiliate-section’, [‘isAffiliate’ => true]);

It ensures that the widget is only displayed to the logged-in affiliates.

For further insights on optimizing Magento performance, you might find our Webinar Recap on Tuning Magento to Unbelievable Speeds beneficial.

Full Page Cache (FPC) Impact

How Varnish Responds Differently to Separate Keys

Each unique cache key creates a different version in Varnish.

  • Cache key A (guest) → one cached page
  • Cache key B (affiliate) → another cached page

This way affiliates and guest users get their own versions stored. However, creating too many variations can lead to filling up cache storage fast and your hit rates drop.

Here’s how you can avoid cache bloat:

Use Magento’s cache reports or varnishstat to check your cache performance regularly.

Create variations only when it’s absolutely necessary.

Stick to simple values or booleans like user type or country instead of using things like timestamps and user IDs.

You need to cap variations. For example, if you have 3 locations x 2 devices x 2 flags, you’ve got a total of 12 versions, which is probably more than what you need.

Best Practices

You need to follow some best practices to keep your cache strategy up and running.

Keep Context Keys Minimal and Deterministic

  • Leverage booleans or small enums (for example, guest|customer, mobile|desktop).
  • Try to steer clear of anything that changes on each request.

Document Which Flags Impact Cache

  • Maintain a Confluence page or README.md that lists the following:
    • Each custom context
    • Where the custom contexts are injected
    • Which pages or blocks consume them
  • Along with your code, version-control these docs as well.

Monitor Varnish Hit/Miss Ratio When Deploying Changes

  • To make sure that the new contexts haven’t hurt the performance, schedule a quick varnishstat check after deploying the changes.
  • In case there’s a drop of more than 5-10% in cache hit rate, remove unnecessary contexts or roll back the changes.

Conclusion

A successful store should have performance and personalization working side-by-side. By extending Http\Context, adding custom flags to your cache keys, and knowing when to turn back to JavaScript-driven private content, you’ll be able to deliver flawless personalized experiences minus any cache overloads. Remember, the two golden rules of contexts – less is more and track early, track often. Now, apply what you learned in this blog and take your Magento store to new heights.

FAQs

Cache contexts are special settings/parameters (for example, custom flags, store view, customer groups, etc.) tracked by Magento to determine which cached block or page to show to users. With cached contexts, you prepare Magento to show different cached versions to different users based on the context value.
You can create a separate custom class by extending \Magento\Framework\App\Http\Context or set a custom flag (for example, is_affiliate_user or user_country), which will allow Magento to generate different cache keys automatically.
When you are dealing with data that is fully user-specific and it’s not meant to be shared across users (like welcome messages, personalized dashboards, or minicart items), using private content makes more sense. Instead of caching them server-side, you can leverage Magento’s customer-data JavaScript module for this.
Every unique context value combination generates a separate cached page in Varnish. With too many combinations, you can fill up your cache storage pretty fast, which can lead to lowering cache hit rates and affecting your site’s performance as a result. Make sure you are considering only the truly necessary variations.
Once deployed, you can track hit/miss ratios by leveraging tools like Magento’s built-in cache reports or varnishstat. A 5-10% drop in cache hit rate is definitely a major concern. In such cases, you can simplify your contexts or roll back the changes.

Get eCommerce insights, tips, and best practices.

Picture of Shahed Jamal
Shahed Jamal

Leading e-commerce tech implementation & management with 9 years of experience specialised in Adobe commerce. Driving end to end solutions for e-commerce including ERP, Commerce, OMS, PIM, Omnichannel, CRM, CRO etc.

You May Also Like

Latest Blogs

Magento Development Company

Let’s talk

Our Offices

DTECH, Techno Hub 1, Dubai Silicon Oasis Authority, United Arab Emirates – Dubai – United Arab Emirates

Singapore

Codilar Digital Pte Ltd, 68 Circular Road, #02-01, 049422, Singapore

India

Bengaluru

7th Floor, Jupiter Block ,Prestige Tech Park, Kadubeesanahalli, Bellandur Amanikere, Bengaluru, Karnataka 560103

Calicut

SBC No 4 & 6 upper basement, Sahya Building
KSITIL SEZ, Cyberpark Kozhikode Park Rd, Nellikkode, Kozhikode, Kerala 673016

Kolkata

Astra Towers, ANO -523 ,North Block, Action Area IIC, Newtown, Kolkata, West Bengal 700135

Oman

Building No. 2/796, Way No. 43, Block No. 336, Al Khud 132, Muscat, Oman

Codilar

© Copyright Codilar 2025. All Rights Reserved. Privacy Policy

Send Feedback

Request PWA Demo