HomeDev GuideRecipesAPI Reference
Dev GuideAPI ReferenceUser GuideGitHubNuGetDev CommunityOptimizely AcademySubmit a ticketLog In
Dev Guide

Configure Visual Builder

Visual Builder is the editor interface in Optimizely Content Management System (CMS 13) that makes content creation and layout building intuitive and accessible to non-technical users.

Visual Builder provides a layout and composition system for building structured content from reusable components. Content managers design, modify, and reuse blueprints directly in the CMS 13 UI.

Visual Builder overview

Visual Builder organizes content into three hierarchical building blocks that separate layout from content data:

  • Pages – The main, routable entry point of Visual Builder. A page extends a regular CMS page with access to the layout system and UnstructuredData, an array of editor-added content. UnstructuredData is an array property on pages and sections that stores inline content data added by the editor. Pages use the outline layout type, a flat, ordered list of sections.
  • Sections – A vertical chunk of a page. A section extends a block with access to the layout system and UnstructuredData. Sections use the grid layout type, a hierarchical structure of rows, columns, and elements.
  • Elements – The smallest building block in Visual Builder. An element contains the content data and extends a block, but restricts the property types it supports. Elements are leaf nodes and do not have children.

Layout system

The layout system controls how Visual Builder arranges pages and sections into structured, renderable hierarchies.

Pages and sections use the layout system in Visual Builder. The layout maintains structure, styling, and content references. Two layout types exist: outline and grid.

Outline

The outline layout defines a flat, ordered list of section nodes. Each section node binds to the inline content data of that section. Visual Builder stores the section content data in the UnstructuredData property of the page.

The following example shows a layout for a page with two sections:

📘

Note

A property binding is a reference that links a layout node to its corresponding content data in UnstructuredData.

{
   "type": "outline",
   "nodes": [
      {
         "type": "section",
         "name": "Hero",
         "propertyBinding", "UnstructuredData[28C004E487B041F090A7877DA42E6C55]"
      },
      {
          "type": "section",
          "name": "Teasers",
          "propertyBinding", "UnstructuredData[43CBB515BF71440480CEAE14A2399205]"
       }
   ]
}

Grid

Sections use the grid layout, which defines a hierarchical structure of rows, columns, and elements. Each element node binds to the inline content of that element. Visual Builder stores element content data in the UnstructuredData property of the section.

The following example shows a layout for a hero section with a single row, two columns, and multiple elements:

{
   "type": "grid",
   "nodes": [
      {
         "id": "F2796537CDB4427C970EE48DF7647A16",
         "type": "row",
         "nodes": [
            {
               "id": "BC6E9722983D41B5990C4608811FD836",
               "type": "column",
               "nodes": [
                  {
                     "type": "component",
                     "propertyBinding": "UnstructuredData[6477A4CE3A7F45A680DBB183E808C748]"
                  },
                  {
                     "type": "component",
                     "propertyBinding": "UnstructuredData[047F427B24EF4CABB0BC0F089C9A95B5]"
                  }
                ]
            },
             {
               "id": "FA7640A627AA466F8AAF71985782482C",
               "type": "column",
               "nodes": [
                  {
                     "type": "component",
                     "propertyBinding": "UnstructuredData[1353D9483DA3417A93B8BEB95E90F850]"
                  }
                ]
            }
          ]
      }
    ]
}

Content manager editing

Content managers use Visual Builder to author and arrange elements directly in the UI.

🚧

Important

Custom editors are not supported. Optimizely plans to add this functionality in a future release.

Display templates

Display templates let developers define styling options that content managers apply to layout nodes without changing code.

Developers define display templates to control the styles available on nodes. Content managers then apply styles to nodes in the Visual Builder UI.

Display templates have an ordered list of settings, each with several options the editor picks from. Optimizely Graph indexes the selected display templates and settings with the page and delivers the data to the front end. The delivery site then renders the content.

Define display templates

Display template definitions control which styling options are available in the editor. Associate a display template with a baseType, a specific contentType, or a nodeType.

  • Base type – Associate display templates with a base type. Values for the baseType property are experience, section, and component.
  • Content type – Associate display templates with a content type. Use any content type key derived from the base types experience, section, and component.
  • Node type – Associate display templates with a node type. Values for the nodeType property are row and column.

Display setting editors

The following values are available for the editor on the display settings:

  • select – Drop-down list supporting single-item selection. Default yes.
  • checkbox – Toggle. Default no.

Example display templates

The following example shows a display template available for sections. When selected, the template lets the editor change the color scheme and choose whether to highlight the section.

  • The color scheme setting lets the editor choose default, primary, and secondary.
  • The highlight setting is a checkbox with a true or false value.
  • The JSON shows the format when creating the display template using the CMS REST API and the Create display template endpoint.
{
   "key": "defaultSection",
   "displayName": "Default Section",
   "baseType": "section",
   "isDefault": true,
   "settings": {
      "colorScheme": {
         "displayName": "Color scheme",
         "editor": "select",
         "sortOrder": 10,
         "choices": {
            "default": {
               "displayName": "Default",
               "sortOrder": 10
            },
            "primary": {
               "displayName": "Primary",
               "sortOrder": 20
            },
            "secondary": {
               "displayName": "Secondary",
               "sortOrder": 30
            }
         }
      },
      "highlight": {
        "displayName": "Highlighted",
        "editor": "checkbox",
        "sortOrder": 10
      }
   }
}

Treat templates, settings, and options as abstractions. Do not add dependencies on how the delivery site uses them. In this example, defining color schemes as "Primary" and "Secondary" instead of "red" and "green" keeps the data meaningful across channels. This approach also protects your data if brand colors change to "orange" and "purple".

Composition

Optimizely Graph indexes the composition of joined page and section layouts as a queryable object model. The delivery site gets structured access to layout and content data.

Query this object model through Optimizely Graph. For information on queries, see Optimizely Graph documentation.

The following example shows the data indexed to Optimizely Graph for a page with a single section:

{
   "_metadata": {
      "key": "151A1E2E6358462FB3ABF0705FDCD03E",
      "locale": "en",
      "version": "1",
      "types": [
         "BlankExperience",
         "_Experience",
         "_Page",
         "_Content"
      ],
      "displayName": "My Experience",
      "status": "Draft",
      "container": "C4B3DD92E0144001A046E010434DF13D",
      "path": [
         "151A1E2E6358462FB3ABF0705FDCD03E"
      ],
      "routeSegment": "my-experience",
      "lastModified": "...",
      "lastModifiedBy": "search-indexer",
      "created": "...",
      "createdBy": "search-indexer",
      "locales": [
         "en"
      ],
      "url": {
         "hierarchical": "/en/my-experience/",
         "internal": "cms://content/151A1E2E6358462FB3ABF0705FDCD03E?loc=en&ver=1",
         "default": "/en/my-experience/",
         "type": "HIERARCHICAL"
      }
   },
   "composition": {
      "displayName": "My Experience",
      "key": "151A1E2E-6358-462F-B3AB-F0705FDCD03E",
      "type": "BlankExperience",
      "nodeType": "experience",
      "displayTemplateKey": null,
      "displaySettings": [],
      "nodes": [
         {
            "displayName": "Hero",
            "key": "6A953CCD-741A-4B1B-B6E5-562434DC3ED1",
            "type": "BlankSection",
            "nodeType": "section",
            "displayTemplateKey": "defaultSection",
            "displaySettings": [
               {
                  "key": "colorScheme",
                  "value": "primary"
               },
               {
                  "key": "highlight",
                  "value": "true"
               }
            ],
            "nodes": [
               {
                  "key": "FB554790-2871-45D7-9502-DA8B4CAD4B13",
                  "nodeType": "row",
                  "displayTemplateKey": null,
                  "displaySettings": [],
                  "nodes": [
                     {
                        "key": "DE42C8FB-AF10-4D31-8C16-CE12EB03B35D",
                        "nodeType": "column",
                        "displayTemplateKey": null,
                        "displaySettings": [],
                        "nodes": [
                           {
                              "key": "6ED087C6-7504-45AC-9295-6AD568978EFF",
                              "type": "HeadingElement",
                              "nodeType": "component",
                              "displayTemplateKey": null,
                              "displaySettings": [],
                              "component": {
                                 "_metadata": {
                                    "displayName": "Heading",
                                    "types": [
                                       "HeadingElement",
                                       "_Component",
                                       "_Content"
                                    ],
                                    "status": "Draft",
                                    "lastModified": "...",
                                    "locale": "en"
                                 },
                                 "Heading": "My Heading"
                              }
                           }
                        ]
                     }
                  ]
               },
               {
                  "key": "598A9EC0-FCAE-40FF-8283-E7056A9CA637",
                  "nodeType": "row",
                  "nodes": [
                     {
                        "key": "C413CC9B-0977-4E1E-821A-389CB212C129",
                        "nodeType": "column",
                        "displayTemplateKey": null,
                        "displaySettings": [],
                        "nodes": [
                           {
                              "key": "106B2993-1766-4D9A-834D-0E11CF9F491F",
                              "type": "TextElement",
                              "nodeType": "component",
                              "component": {
                                 "_metadata": {
                                    "displayName": "Text",
                                    "types": [
                                       "TextElement",
                                       "_Component",
                                       "_Content"
                                    ],
                                    "status": "Draft",
                                    "lastModified": "...",
                                    "locale": "en"
                                 },
                                 "Body": {
                                    "html": "<p>Here goes some <b>stuff</b></p>",
                                    "json": "{\"type\":\"richText\",\"children\":[{\"type\":\"paragraph\",\"children\":[{\"text\":\"Here goes some \"},{\"text\":\"stuff\",\"bold\":true}]}]}"
                                 }
                              }
                           }
                        ]
                     }
                  ]
               }
            ]
         }
      ]
   }
}

Blueprints

Blueprints let content managers save authored content as reusable templates, reducing repetitive setup for pages and sections with common layouts.

A blueprint is a template stored in the blueprints folder under root in the page tree. Save page and section content as blueprints to reuse layouts.

Create blueprints only through the editor in the UI. The CMS 13 REST API does not support blueprint creation. See Manage blueprints.

When a blueprint instantiates a page or section, Visual Builder copies the layout to the content. The content is detached and not connected to the source blueprint. Changes to the base blueprint do not affect instances created from it.

Preview

Previewing content in Visual Builder validates the layout and content before publishing.

CMS 13 integrates with delivery sites using the communicationInjector. For information about configuring communication between CMS 13 and the site, see Enable live preview.