Disclaimer: This website requires Please enable JavaScript in your browser settings for the best experience.

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

Configure Visual Builder

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

Visual Builder lets you build content and offers a layout system and composition system containing small bits of content. It lets content managers design, modify, and reuse blueprints directly in the CMS (SaaS) user interface.

Visual Builder overview

Visual Builder content has the following:

  • 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 through a composition. Experiences use the outline layout type, a flat, ordered list of sections and or section-enabled components.
  • 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 through a composition-like experience. 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 constitute a leaf or terminal node in an experience and do not have children.

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 example

The outline layout defines a flat, ordered list of sections or section-enabled component nodes.

The following is an example of how an experience created through the API could look for a simple experience with one section and one section-enabled block:

{
  "contentType": "BlankExperience",
  "locale": "en",
  "container": "43f936c99b234ea397b261c538ad07c9",
  "status": "published",
  "displayName": "Sample Experience",
  "composition": {
    "nodeType": "experience",
    "layoutType": "outline",
    "nodes": [
      {
        "displayName": "A Section",
        "nodeType": "section",
        "layoutType": "grid",
        "component": {
          "contentType": "BlankSection"
        }
      },
      {
        "displayName": "A Section enabled block",
        "nodeType": "component",
        "component": {
          "contentType": "TextBlock",
          "properties": {
            "Heading": "An heading"
          }
        }
      }
    ]
  }
}

Grid example

Sections use the grid layout, which defines a hierarchical structure of rows, columns, and elements.

The following is an example of how an experience created through the API could display for a hero section with a single row, two columns, and a few elements or components:

{
  "contentType": "BlankExperience",
  "locale": "en",
  "container": "43f936c99b234ea397b261c538ad07c9",
  "status": "published",
  "displayName": "Sample Experience",
  "composition": {
    "nodeType": "experience",
    "layoutType": "outline",
    "nodes": [
      {
        "displayName": "A Section",
        "nodeType": "section",
        "layoutType": "grid",
        "component": {
          "contentType": "BlankSection"
        },
        "nodes": [
          {
            "displayName": "A row",
            "nodeType": "row",
            "nodes": [
              {
                "displayName": "First column",
                "nodeType": "column",
                "nodes": [
                  {
                    "displayName": "A text block",
                    "nodeType": "component",
                    "component": {
                      "contentType": "TextBlock",
                      "properties": {
                        "Heading": "I am in first column"
                      }
                    }
                  }
                ]
              },
              {
                "displayName": "Second column",
                "nodeType": "column",
                "nodes": [
                  {
                    "displayName": "Another text block",
                    "nodeType": "component",
                    "component": {
                      "contentType": "TextBlock",
                      "properties": {
                        "Heading": "I am in the second column"
                      }
                    }
                  }
                ]
              }
            ]
          }
        ]
      }
    ]
  }
}

Content managers

Visual Builder lets content managers author and edit content using the elements from the editing user interface.

🚧

Important

You cannot add custom editors. Optimizely plans to add this functionality later.

Display templates (styles)

The developer defines the styles available on the nodes as display templates. After developers create the styles, the content manager can set styles on different nodes in the Visual Builder UI.

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 then renders 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 component.
  • Content type – Associate display templates with a content type. You can 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 editor on the display settings supports the following values:

  • select – Drop-down list supporting single-item selection. Default or fallback is Yes.
  • checkbox – Toggle true or false. Default or fallback is No.

Display template example

The following example shows a display template available for sections, which, when selected, lets 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 example

The following example shows how to create an experience through the API with a section that uses defined display templates:

{
  "contentType": "BlankExperience",
  "locale": "en",
  "container": "C4B3DD92E0144001A046E010434DF13D",
  "status": "draft",
  "displayName": "Styled Experience",
  "composition": {
    "displayName": "My Experience",
    "key": "151A1E2E-6358-462F-B3AB-F0705FDCD03E",
    "type": "BlankExperience",
    "nodeType": "experience",
    "displayTemplateKey": null,
    "displaySettings": [],
    "nodes": [
      {
        "displayName": "Hero",
        "type": "BlankSection",
        "nodeType": "section",
        "displaySettings": {
          "displayTemplate": "defaultSection",
          "settings": {
            "colorScheme": "primary",
            "highlight": "true"
          }
        },
        "nodes": [
          {
            "nodeType": "row",
            "nodes": [
              {
                "nodeType": "column",
                "nodes": [
                  {
                    "nodeType": "component",
                    "component": {
                      "contentType": "HeadingElement",
                      "properties": {
                        "Heading": "My Heading"
                      }
                    }
                  }
                ]
              }
            ]
          }
        ]
      }
    ]
  }
}

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": "component",
                    "displayTemplateKey": null,
                    "displaySettings": [],
                    "component": {
                      "_metadata": {
                        "displayName": "Heading",
                        "types": [
                          "HeadingElement",
                          "_Component",
                          "_Content"
                        ],
                        "status": "Draft",
                        "lastModified": "...",
                        "locale": "en"
                      },
                      "Heading": "My Heading"
                    }
                  }
                ]
              }
            ]
          }
        ]
      }
    ]
  }
}

Blueprints example

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

You can create blueprints with the editor in the UI or through the API. See Save as blueprint. The following example shows how a section model saved through the API could look like:

{
  "key": "C78520D10FF64F1AB4A7A731F75B4563",
  "displayName": "A Section blueprint",
  "contentType": "BlankSection",
  "content": {
    "composition": {
      "displayName": "A Section",
      "nodeType": "section",
      "layoutType": "grid",
      "component": {
        "contentType": "BlankSection"
      },
      "nodes": [
        {
          "displayName": "A Row",
          "nodeType": "row",
          "nodes": [
            {
              "displayName": "A Column",
              "nodeType": "column",
              "nodes": [
                {
                  "displayName": "An Element",
                  "nodeType": "component",
                  "component": {
                    "contentType": "HeadingElement",
                    "properties": {
                      "Heading": "Hello, Section!"
                    }
                  }
                }
              ]
            }
          ]
        }
      ]
    }
  }
}

When you use the blueprint to instantiate an experience or section, Visual Builder copies that layout to the content. Visual Builder detaches the content and does not connect it to the blueprint from which it was created. The instances of the blueprint do not reflect changes to the base blueprint.

Preview

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