Dynamic Blocks and Personalization: Content by Customer Segment
AI generated
M2
di.xml
Magento 2 · Dynamic Blocks · Personalization · Segments
Dynamic Blocks and Personalization
delivering segment-specific content by customer group

A single content block for every visitor leaves conversion potential unused, especially when new customers, returning customers and B2B company accounts have different needs. Dynamic Blocks enable segment-specific content in live operation, without maintaining a separate landing page for every audience and without breaking the Full Page Cache.

17 min read customer segments · dynamic block · Full Page Cache Magento 2.4.x Commerce

1. What sets Dynamic Blocks apart from static content

A regular CMS block shows the same content to every visitor, regardless of whether it is a first-time visitor, a returning customer with purchase history or a B2B company account. A Dynamic Block solves exactly this problem: it defines multiple content variants for the same placement and picks the matching variant at runtime based on conditions such as customer group, customer segment or order history. For editors, the backend handling stays almost identical to a normal block, the personalization happens entirely behind the scenes.

The practical benefit shows up especially with cross-selling banners, welcome messages and seasonal offers. A new customer sees an introductory promotion, a returning customer with high cart value sees a premium offer, a B2B customer sees company-account-specific content, all through the same Dynamic Block at the same spot in the layout. This form of personalization considerably increases the relevance of the displayed content, without needing a separate page maintained for every audience.

2. Foundation: customer segments as audience definitions

Before a Dynamic Block can be used meaningfully, it needs a clean definition of audiences through customer segments. A customer segment groups customers based on criteria such as customer group, number of previous orders, last order value or website assignment. These segments are recalculated regularly through an indexer and form the basis that Dynamic Blocks later refer to.

A common beginner mistake is creating too many, too granular segments, which makes maintenance in the backend confusing and unnecessarily extends indexer runtime. It has proven effective to start with a small number of clearly defined segments, for example new customers, returning customers with fewer than three orders, returning customers with more than three orders and B2B company accounts, and to refine this structure only once actual demand is proven.


<!-- app/code/Mironsoft/DynamicBlockPersonalization/etc/adminhtml/system.xml -->
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd">
    <system>
        <section id="mironsoft_dynamicblock" translate="label" type="text" sortOrder="200"
                 showInDefault="1" showInWebsite="1" showInStore="1">
            <label>Dynamic Block Personalization</label>
            <tab>mironsoft</tab>
            <resource>Mironsoft_DynamicBlockPersonalization::config</resource>
            <group id="general" translate="label" type="text" sortOrder="10" showInDefault="1">
                <label>General</label>
                <field id="enabled" translate="label" type="select" sortOrder="10" showInDefault="1">
                    <label>Enable personalization</label>
                    <source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
                </field>
                <field id="fallback_segment" translate="label" type="text" sortOrder="20" showInDefault="1">
                    <label>Fallback segment ID</label>
                    <comment>Used when no segment matches</comment>
                </field>
            </group>
        </section>
    </system>
</config>

3. Creating a dynamic block: conditions and assignment

A Dynamic Block is created in the backend under Marketing, with a date range, an assignment to one or more customer segments and the actual content per variant. The condition logic works additively: when a visitor matches multiple segments at once, the priority of the dynamic block assignment decides which variant gets served. This prioritization should be documented deliberately, because otherwise it quickly becomes unclear which rule wins in a conflict once the number of blocks grows.

For the technical assignment in a custom module, a plugin on the segment resolver that checks whether a logged-in customer belongs to a particular segment is worthwhile. This resolver is used both by the native dynamic block logic and by custom extensions, for example when geodata or the device used should also feed into personalization in addition to segment membership.


<?php
declare(strict_types=1);

namespace Mironsoft\DynamicBlockPersonalization\Model;

use Magento\Customer\Model\Session as CustomerSession;
use Magento\TargetRule\Model\ResourceModel\Rule\CollectionFactory as RuleCollectionFactory;

/**
 * Resolves which dynamic block variant applies to the current visitor.
 */
class SegmentResolver
{
    /**
     * @param CustomerSession $customerSession Current customer session
     * @param RuleCollectionFactory $ruleCollectionFactory Factory for target rule collections
     */
    public function __construct(
        private readonly CustomerSession $customerSession,
        private readonly RuleCollectionFactory $ruleCollectionFactory,
    ) {
    }

    /**
     * Determines the highest priority segment ID that matches the current visitor.
     *
     * @param int $fallbackSegmentId Segment ID used when no match is found
     * @return int Resolved segment ID
     */
    public function resolveSegmentId(int $fallbackSegmentId): int
    {
        if (!$this->customerSession->isLoggedIn()) {
            return $fallbackSegmentId;
        }

        $customerGroupId = (int) $this->customerSession->getCustomer()->getGroupId();
        $orderCount = (int) $this->customerSession->getCustomer()->getData('order_count');

        // Simplified segment matching — real implementation queries segment index tables
        if ($orderCount === 0) {
            return 10; // new customer segment
        }

        if ($orderCount > 3) {
            return 20; // loyal customer segment
        }

        return $fallbackSegmentId;
    }
}

4. Placement in layout and Page Builder pages

There are two ways to place the block: as a classic block through layout XML, or as a building block directly inside a Page Builder page. Through layout XML, the Dynamic Block is attached to a fixed container position, for example above the product grid on a category page. Inside Page Builder, the dynamic block appears as its own content type in the editor panel and can be placed freely within the page by editors, without a developer having to touch the layout.

For Hyvä themes it matters that the renderer block for dynamic content does not trigger an additional AJAX request for segment resolution, but makes the decision server side during the initial render. That keeps the implementation in line with Hyvä's principle of loading as little extra JavaScript as possible, and avoids a visible content jump after the page's first render.

5. Full Page Cache: why personalized blocks do not break it

Personalized content and Full Page Cache seem contradictory at first: if every visitor should see different content, how can a page be cached as a whole? The solution lies in the separation between static, cacheable page content and the personalized fragment, which is added through an AJAX follow-up load or client side caching of the respective segment assignment in local storage. The Dynamic Block itself never becomes part of the cached HTML response, it is delivered as a placeholder container that only gets filled with the matching segment after the cache hit.

This architecture is deliberately designed so that Full Page Cache and personalization work at the same time, without needing a separate cached page variant per segment. It matters to keep the segment resolution itself performant, for example through a dedicated, lightweight endpoint that only returns the segment ID instead of recomputing the entire personalized HTML block on every request.


# Verify that dynamic block placeholders are not baked into the cached HTML response
curl -s -H "Cache-Control: no-cache" https://shop.example.com/ | grep -o 'data-dynamic-block-placeholder="[^"]*"'

# Check Full Page Cache hit status for a personalized landing page
curl -sI https://shop.example.com/ | grep -i x-magento-cache-debug

6. Extending custom segmentation rules through plugins

The native conditions for customer segments cover many standard cases, but not every personalization requirement. Through a plugin on the rule evaluator, custom conditions can be added, for example membership in an external loyalty tier that is not maintained in Magento itself but queried through a third-party API. It matters to cache the result of this external lookup briefly, so that not every page view triggers an external API call.

For more complex personalization scenarios, such as weather-dependent or location-based content, the same mechanism that applies to customer segments can be reused, only that the condition evaluation draws on additional context data from the request. This extensibility makes Dynamic Blocks a flexible foundation for personalization that goes considerably beyond plain customer group logic.

7. Personalization for B2B company accounts and customer groups

In a B2B context, personalization gains an additional dimension: not just the individual customer but the entire company account with its roles and approval workflows influences which content is relevant. A company account administrator might see hints about order approvals, while a plain employee account uses the same area for product recommendations from the agreed assortment. A Dynamic Block with a condition on the company account role covers this case without requiring a completely separate content strategy for B2B.

Customer groups remain the simplest and most robust foundation for personalization, because they are already anchored in many places in Magento, for example in price rules and product visibility. A dynamic block that primarily relies on customer groups and only secondarily falls back to finer customer segments is, in practice, more maintainable than a solution built purely on complex segment logic.

8. Measuring success: A/B tests and evaluation by segment

Personalized content without success measurement remains a guess. Every Dynamic Block should have a distinct tracking attribute that gets passed to the analytics platform on click or conversion, split by the variant that was served. That way it becomes provable whether the premium variant for returning customers actually achieves higher conversion rates than a generic variant, or whether personalization makes no measurable difference in a given case.

For reliable conclusions, a controlled A/B test is recommended, where part of a segment sees the generic variant despite being a match. Only this comparison within the same segment shows whether the personalization itself makes the difference, rather than merely confirming the already different purchase readiness of different segments.

9. Personalization approaches compared

Choosing the right personalization approach is worth a look at effort, cache compatibility and data freshness.

Approach Cache compatibility Freshness Suitable for
Dynamic block + segment Very good (AJAX fragment) After indexer run Banners, cross-selling, welcome messages
Server side rendering without cache Poor, disables FPC Immediate Pages with an inherently short dwell time
Client side JavaScript Good Immediate Light UI adjustments, Hyvä compatible
External personalization engine Depends on the vendor Immediate, ML based Large catalogs, complex recommendations

For most Magento shops, the combination of dynamic block and customer segment is the best starting point, because it is natively anchored in Magento, works together with the Full Page Cache and requires no additional third-party license. Only for very complex, ML-driven recommendations is it worth looking at external personalization engines.

Mironsoft

Magento 2 & Hyvä: personalization, segmentation and cache architecture

Content the same regardless of audience?

We design Dynamic Blocks and customer segments that fit your shop, implemented cache compatible and with clear success measurement per segment.

Segment strategy

Clear, maintainable customer segments instead of granular rule sprawl

Cache compatible implementation

AJAX fragments instead of disabling Full Page Cache

Success measurement

Tracking and A/B tests per segment and content variant

10. Summary

Dynamic Blocks solve the basic problem of static content blocks: not every visitor has the same needs, and a single piece of content for everyone wastes conversion potential. Built on cleanly defined customer segments, personalization can be implemented so it works together with the Full Page Cache instead of disabling it, by loading the personalized share as a lightweight fragment.

The biggest lever lies in combining a small number of clearly defined segments, clean prioritization for overlaps and consistent success measurement per variant. Bringing these three building blocks together yields a personalization solution that works both for simple cross-selling banners and for more complex B2B company account scenarios.

Dynamic Blocks and personalization — the essentials at a glance

Foundation

Customer segments define audiences, a small number of clear segments is more maintainable than granular rule sprawl.

Cache compatibility

Personalized content as an AJAX fragment, the static rest of the page stays Full Page Cache capable.

Extensibility

Custom segmentation rules through a plugin on the rule evaluator, including external data sources.

Success measurement

Tracking per variant and an A/B test within the same segment for reliable conclusions.

11. FAQ: Dynamic Blocks and personalization

1Difference between a Dynamic Block and a regular CMS block?
A Dynamic Block picks the matching variant at runtime based on conditions, a CMS block always shows the same content.
2Do you need Magento Commerce for this?
Yes, Dynamic Blocks and customer segments belong to Magento Commerce, in Open Source you would have to build it yourself.
3How many segments should you create?
A few clearly defined segments at first, more only once actual demand is proven, to keep maintenance manageable.
4How does this interact with the Full Page Cache?
Personalized blocks are embedded as placeholders and loaded via AJAX, the rest of the page stays cacheable.
5What happens when multiple segments overlap?
The priority of the assignment decides which variant wins, this rule should be documented.
6Can custom conditions be added?
Yes, via a plugin on the rule evaluator, for example external loyalty tiers, with brief caching of the lookup.
7How does B2B personalization work?
Through a condition on the company account role for different content per role within the same company account.
8How do you measure success?
Through tracking per variant plus a controlled A/B test within the same segment.
9Compatible with Page Builder?
Yes, as its own content type inside Page Builder pages, freely placeable by editors.
10When does an external engine pay off?
For very large catalogs with complex ML recommendations. Native Dynamic Blocks are enough for standard cases.