HomeDev GuideAPI Reference
Dev GuideAPI ReferenceUser GuideLegal TermsGitHubNuGetDev CommunityOptimizely AcademySubmit a ticketLog In
Dev Guide

Visual Builder

Information on Visual Builder in Optimizely CMS (SaaS).

The Visual Builder in Content Management System (CMS) (SaaS) is a way of building content that offers a layout and composition system with small bits of content. Visual Builder content has the following pieces:

  • Experiences – The main, routable entry point of the Visual Builder and an extension of a page. An experience has the same features as a page but has access to the Layout system and UnstructuredData, an array of content the editor adds. Experiences use the outline layout type, a flat, ordered list of sections.
  • Sections – A vertical "chunk" of an experience and an extension of a block. A section has the features of a block but also has access to the Layout system and UnstructuredData like experiences. Sections use the grid layout type, which is a hierarchical structure of rows, columns, and elements.
  • Elements – The smallest building block in Visual Builder with the actual content data of an experience. An element is also an extension of a block but has restrictions on what property types it supports. Elements are considered a leaf or terminal node in an experience and do not have children.

📘

Note

For information on Visual Builder, see the Optimizely user guide, specifically the Visual Builder concepts article.

Layout system

Experiences and sections have access to the layout system in Visual Builder. The layout maintains the structure, styling, and content references. There are two types of layouts: outline and grid.

Outline

The outline layout defines a flat, ordered list of section nodes. Each section node contains a property binding to the section's inline content data. Visual Builder stores the content data for the sections in the experience's UnstructuredData.

The following is an example of how a layout could look for a simple experience with two sections:

{
   "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 contains a property binding to the element's inline content. Visual Builder stores the content data for the elements in the section's UnstructuredData.

The following is an example of how a layout could look for a hero section with a single row, two columns, and a couple of elements.

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

Editors

Visual Builder uses editors to author content using the elements from the editing user interface.

🚧

Important

You cannot add custom editors. There are plans to add this functionality later.

Display templates (styles)

The developer defines the styles available on the nodes as display templates. After the styles are created, the editor can set styles on different nodes in the Visual Builder UI. See the end-user guide on Select styles.

Display templates can have an ordered list of settings, each with several options from which the editor can pick. Optimizely Graph indexes the selected display templates and settings with the experience and delivers it to the front end. The delivery site must then render the content.

Define display templates

Visual Builder defines the available display templates and settings for the editor during the definition of display templates. You can 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 element.
  • Content type – Associate display templates with a content type. You can use any content type key derived from the base types experience, section, and element.
  • 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:

EditorDescriptionDefault or Fallback
selectDrop-down list supporting single-item selection.Yes
checkboxToggle true or false.No

Example display templates

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

  • The color scheme setting lets the editor choose options 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 (SaaS) 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
      }
   }
}

View templates, settings, and options as abstractions. Avoid adding dependencies to how one uses them in the delivery site. In this example, defining color schemes as "Primary" and "Secondary" instead of "red" and "green" ensures that the data makes sense across multiple channels. It also future-proofs your information in case you change the brand colors for the delivery site to use "orange" and "purple", for example.

Composition

For each experience, Optimizely Graph indexes the composition of the joined layouts of the experience and its sections as an object model. You can query this object model through Optimizely Graph. For information on how to run queries and interact with Optimizely Graph, see the Optimizely Graph documentation.

Here is an example of how the data index to Optimizely Graph might look for an experience 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": "element",
                              "displayTemplateKey": null,
                              "displaySettings": [],
                              "element": {
                                 "_metadata": {
                                    "displayName": "Heading",
                                    "types": [
                                       "HeadingElement",
                                       "_Element",
                                       "_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": "element",
                              "element": {
                                 "_metadata": {
                                    "displayName": "Text",
                                    "types": [
                                       "TextElement",
                                       "_Element",
                                       "_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

You can save content authored using Visual Builder as a blueprint. A blueprint should be considered a template in the folder blueprints found beneath root in the page tree. You can save experience and section content as blueprints.

You can only create blueprints with the editor in the UI; you cannot use the CMS (SaaS) REST API to do so. See the end-user documentation Save as blueprint.

When you use the blueprint to instantiate an experience or section, Visual Builder copies that layout to the content. The content is detached and not connected to the blueprint from which the content was created. Changes to the base blueprint are not reflected in the instances of the blueprint.

Preview

Previewing the experience is an important function of the Visual Builder. How the CMS integrates with the delivery sites builds on the communicationInjector. For information about setting up communication between CMS (SaaS) and the site, see Enable live preview.