Learn why Gartner just named Builder a Cool Vendor

Announcing Visual Copilot - Figma to production in half the time

Builder.io logo
Contact Sales
Platform
Developers
Contact Sales

Blog

Home

Resources

Blog

Forum

Github

Login

Signup

×

Visual CMS

Drag-and-drop visual editor and headless CMS for any tech stack

Theme Studio for Shopify

Build and optimize your Shopify-hosted storefront, no coding required

Resources

Blog

Get StartedLogin

in beta

Use variant containers for personalization and scheduling features for content. You can serve different content variants to specific audiences or at scheduled times without requiring duplication of the entire Page or Section, giving you a single source of truth.

Use cases include:

  • Targeted content: Show different promotional messages to various customer segments, such as new visitors, returning customers, or users from different geographic locations.
  • Date-specific or scheduled content: Instead of creating and scheduling multiple Page copies, users can schedule variants to appear at designated times.
  • Localize content for different locales: Display localized content based on the user’s country or language preference, such as currency or language settings.
  • User journey-based personalization: Adapt based on where a user is in their journey, like first-time visitors, repeat customers, or users who have made it further through the funnel.

To use variant containers, you must be using React Gen 1 SDK version 5.0.2 or later. For more information on the available SDKs, read SDK Comparison.

Personalize a block to enable features such as targeting and scheduling just for that block. For example, if you have a Section that you'd like the content to change for depending on the user or date, you'd personalize the block and then create a variant to your specifications.

To personalize a block:

  1. Select the block you want to personalize.
  2. Click the down arrow next to the Edit button to open the flyout menu.
  3. To make this block dynamic, select Personlize. The Options tab displays a Variants section.
  4. Click the + Variant button to specify Variant 1. When a Variant section within the Options tab is open, that is the variant that you are editing. To display the default variant, close all variant sections.
  5. Select any targeting for the variant. For example, if you only want this particular variant to show when there's another item in already in the visitor's cart, you might configure the query to be Item in cart is and choose the product.
  6. Select dates and times to start and end if needed.

When editing a variant, you can bind and choose data depending on the requirements of each variant.

Notice that when a block has been personalized, in addition to having Variants as an option in the Options tab, the Layers tab also marks the block as personalized.

To enable personalization targeting, set global attributes on the client side. These attributes persist in cookies across page refreshes. For example, the code snippet below sets a global attribute of the audience as vip:

builder.setUserAttributes({ 
  audience: 'vip' 
})

Using global attributes means that all personalization containers on the page automatically show the variant matching these attributes. This behavior is independent of server-side API calls, which determine the entries returned by the API based on user attributes provided in the request.

To simplify targeting logic, consider sending the same attributes to both the API and the client.

As a general practice, set these attributes using real targeting data from your CDP or other user segmentation logic to set attributes accurately.

There's an important distinction between setting user attributes on the client side and sending them to the API.

Server-side attributes (API requests): This approach filters content at the API level, determining which entire content entry is returned. While this was the traditional way of handling personalization, it's generally not recommended for variant containers as it can impact caching and performance:

// Don't do this
export async function getStaticProps() {
  return {
    props: {
      content: await builder.get('page', {
        // These attributes filter which content entry matches using targeting
        userAttributes: {
          // Use sparingly — this affects which entry is returned from the API
        }
      })
    },
  };
}

Client-side attributes (variant containers): This is the recommended modern approach for variant containers. This way you can serve a single cached page to all users and then personalize specific content blocks based on user attributes. This provides better performance and more flexible personalization:

// Do this instead!
export default function Homepage() {
  useEffect(() => {
    // These attributes filter Variant Containers on the client
    // Best practice: Get these from your CDP
    builder.setUserAttributes({
      audience: ["vip"]
    });
  }, []);
}

The most up-to-date approach is to use client-side attributes with variant containers rather than server-side filtering. This provides better performance for a number of reasons:

  • All content variations are server-rendered.
  • Content is filtered using client-side attributes.
  • A single cached page can serve multiple personalized variations.
  • Users see personalized content instantly, even before JavaScript loads.
  • Use variant containers for content with minor variations across multiple targets.
  • Prefer duplicate entries for content with significant variations.
  • Keep the number of variants manageable — fewer than 100.
  • Get targeting attributes from your CDP or user segmentation system.
  • Use client-side attributes for variant containers instead of server-side filtering when possible.

Use the following guidelines to help decide between using variant containers or duplicating content entries. Consider variant containers for streamlined updates with minimal variation but for substantial changes across multiple targets, prefer duplicates.

Use variant containersUse duplicates instead

Consistent content: You’re delivering similar content across multiple targets, with minor variations for different audiences.

Significant content variation: Extensive content changes based on scheduling or targeting.


Scheduled updates: Scheduled updates to specific content blocks at different times without changing the entire Page.


Large-scale updates: Major updates, such as a full homepage, site, or app redesign.

A few variations: A finite number of variants, which don't significantly impact the size of the content entry.

Lots of variants: 100 or more variants, which may exceed the content entry size limit.

for developers

Variant containers enable personalization and scheduling within Builder’s UI. However, for content that requires dynamic adaptation at the server or edge level, the trimHtml() function processes HTML to deliver only the relevant variant based on audience segments, timing, or other criteria.

The trimHTML() function offers several key benefits:

  • Edge caching and SSR-friendly: The trimHtml() function means you can serve personalized content without sacrificing performance. By processing the content on the edge or during SSR, you can still use caching effectively while ensuring users get the appropriate variant.
  • Efficiency: By trimming the HTML before sending it to the client, the resulting HTML is optimized in size, supporting faster load times. This also reduces unnecessary duplication of content.
  • Dynamic Personalization: You can create multiple content variants and dynamically choose which one to display based on user attributes, date, or other rules, all while using a single HTML file.

The trimHtml() function is useful when a project involves edge processing or server-side rendering (SSR). For example, if you need to personalize content based on the user’s location or schedule without sacrificing performance, trimHtml() makes sure the correct variant is selected and served immediately, without unnecessary data being sent to the client.

It’s most helpful when using Next.js, static site generation (SSG), or SSR frameworks that benefit from pre-processed, variant-specific HTML at runtime.

The trimHtml function’s job is to process the personalized content at the edge or server level, based on specific user attributes; for example, audience segmentation, date-based scheduling. The function evaluates the dynamic containers within the HTML and returns a modified HTML string containing the appropriate personalized variant for the user.

The example below uses trimHTML() to select the correct variant at the server level, based on user attributes and A/B test conditions:

import { trimHtml } from '@builder.io/personalization-utils';

// Full HTML with all possible variants
const fullHTML = '... your HTML with variant containers ...';

// Example user attributes, typically parsed from cookies
// for audience segment and date for scheduling
const userAttributes = {
  audience: 'segment-a',
  date: '2025-06-15T12:00:00Z'
};

// Example A/B test data (parsed similarly from cookies or user data)
const abTests = {
  'content-id-1': 'variant-a',    // Specific A/B test variant for content-id-1
  'content-id-2': 'variant-b'     // A/B variant for content-id-2
};

// Trim the full HTML to show only the relevant 
// variant based on attributes and tests
const { html } = trimHtml(fullHTML, { userAttributes, abTests });

To make sure personalized content is delivered correctly, retrieve user attributes stored in the builder.userAttributes cookie, which stores audience and segmentation data.

import { parse } from 'cookie';

function getUserAttributes(req) {
  const cookies = parse(req.headers.cookie || '');
  const builderAttributes = cookies['builder.userAttributes'];
  return builderAttributes ? JSON.parse(builderAttributes) : {};
}

In your request handler, fetch these attributes and pass them to the trimHtml() function to get the appropriate HTML for the user:

const userAttributes = getUserAttributes(req);
const trimmedHTML = trimHtml(fullHTML, userAttributes);

To leverage more with variant containers, read A/B Testing, Targeting, and Scheduling Content.

Was this article helpful?

Product

Visual CMS

Theme Studio for Shopify

Sign up

Login

Featured Integrations

React

Angular

Next.js

Gatsby

Get In Touch

Chat With Us

Twitter

Linkedin

Careers

© 2020 Builder.io, Inc.

Security

Privacy Policy

Terms of Service

Newsletter

Get the latest from Builder.io

By submitting, you agree to our Privacy Policy

Product

Platform Overview

Integrations

What's New

Open Source

Builder

Builder

Mitosis

Mitosis

Mitosis

AI Shell

Mitosis

Micro Agent

Mitosis

GPT Crawler

Qwik

Qwik

Partytown

Partytown

Popular Guides

From Design to Code Guide

Composable Commerce Guide

Headless CMS Guide

Headless Commerce Guide

Composable DXP Guide

Design to Code

Resources

Blog

Knowledge Base

Community Forum

Partners

Templates

Success Stories

Showcase

Resource Center

Frameworks

React

React

Next

Next.js

Qwik

Qwik

Gatsby

Gatsby

Angular

Angular

Vue

Vue

Svelte

Svelte

Remix logo

Remix

Nuxt

Nuxt

Hydrogen

Hydrogen

See All

© 2024 Builder.io, Inc.

Security

Privacy Policy

SaaS Terms

Security & Compliance

Cookie Preferences

Gartner Cool Vendor 2024