Building a TwoColumnWideLeftSection in Optimizely CMS 13 Visual Builder

This post walks through a practical “66% / 33%” section built for Visual Builder using the composition tag helpers: <epi-grid>, <epi-row>, <epi-column>, and <epi-component />. Visual Builder is Optimizely’s layout-and-composition editing experience (originally introduced for CMS SaaS, but the concepts carry over).

What you’re building

A section type that renders:

  • A Bootstrap container
  • One row
  • Two columns:
    • Left: col-md-9
    • Right: col-md-3
  • Each column can contain multiple components (blocks) dropped in Visual Builder.

Step 1: Make sure tag helpers are available in your views

Add the Optimizely tag helpers to Views/_ViewImports.cshtml:

@addTagHelper *, EPiServer.Cms.AspNetCore.TagHelpers

This is the standard ASP.NET Core pattern: adding @addTagHelper in _ViewImports.cshtml makes them available to all views under Views/.

Step 2: Create the section content type

Create a new section model. In CMS 13, sections are typically implemented as block types deriving from EPiServer.VisualBuilder.SectionData and using its Layout property.

Example:

using EPiServer.DataAnnotations;
using EPiServer.VisualBuilder;
namespace alloy13preview.Models.Experiences
{
[ContentType(
GUID = "B4A4C0C2-5B89-4F17-9B10-7AE04A0A9E6D",
DisplayName = "Two columns (wide left)",
GroupName = "Sections")]
public class TwoColumnWideLeftSection : SectionData
{
public override void SetDefaultValues(ContentType contentType)
{
base.SetDefaultValues(contentType);
// Layout.Type should be "grid" for the grid/row/column tag helpers
Layout = new Layout("grid");
var row = new LayoutStructureNode("row");
var left = new LayoutStructureNode("column");
left.DisplaySettings["col"] = "col-md-9";
var right = new LayoutStructureNode("column");
right.DisplaySettings["col"] = "col-md-3";
row.Nodes.Add(left);
row.Nodes.Add(right);
Layout.Nodes.Add(row);
}
}
}

Why store col-md-* in DisplaySettings instead of hardcoding in Razor?

Because DisplaySettings lives on the composition node, meaning it can be:

  • defaulted programmatically (as above),
  • later driven by editor-visible “style choices” if you wire up display templates,
  • and applied cleanly via <epi-styles>.

Step 3: Create the Razor view using composition tag helpers

Create something like:

  • Views/Shared/Sections/TwoColumnWideLeftSection.cshtml (your project may vary)
@model alloy13preview.Models.Experiences.TwoColumnWideLeftSection
<epi-grid class="container">
<epi-row class="row">
<epi-column class="col-12">
<epi-styles>
<epi-style name="col">
<epi-style-map value="col-md-9" class="col-md-9" />
<epi-style-map value="col-md-3" class="col-md-3" />
</epi-style>
</epi-styles>
<epi-component />
</epi-column>
</epi-row>
</epi-grid>

Key points

  • Keep col-12 columns so the layout is same on mobile.
  • <epi-styles> must be inside the <epi-column> tag so it can apply CSS classes to that column tag helper.
  • The style map values (col-md-9, col-md-3) must match what you store in DisplaySettings["col"].

Common pitfalls

1) “My column width classes don’t apply”

Usually one of these:

  • Your DisplaySettings key doesn’t match the <epi-style name="...">.
  • Your DisplaySettings value doesn’t match any <epi-style-map value="...">.
  • You put <epi-styles> outside the parent tag helper you want to style.

2) Bootstrap gutter/layout confusion

Remember:

  • container → fixed widths
  • row → establishes the grid row
  • columns need col-* classes to participate in the grid

Extending this pattern (full width, 3 columns, etc.)

Once you’re comfortable with “row → N columns”, you can:

  • Create FullWidthSection with a single column node and one <epi-column>.
  • Create ThreeColumnSection with three column nodes and three <epi-column> tags.
  • Create variants like:
    • TwoColumnEqualSection (col-md-6 / col-md-6)
    • TwoColumnWideRightSection (col-md-3 / col-md-9)

This keeps each section simple, predictable, and editor-friendly.

Why this is a good CMS 12 → CMS 13 comparison point

In CMS 12, most teams model this as a section block with multiple ContentAreas (Left/Right) and custom editor hints. In CMS 13 Visual Builder, the layout tree plus composition tag helpers becomes the primary mechanism, and DisplaySettings gives you a structured way to flow editor choices into CSS without inventing your own metadata system.

Leave a comment