Builder.io logo
Contact Sales
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

This document provides an overview of the key properties, inputs, and default styles for each built-in component in the Visual Editor.

Use the details below as a starting point to customize the components according to your specific requirements. For details on how to customize them, read Overriding Components.

The built-in components described in this document are the same as those that all roles, except for Contributor, have access to by default in the Visual Editor. All of the components described below are available in the Visual Editor Insert tab, as shown in the next image.

Screenshot of the Visual Editor with the Insert tab pointed out and the three sections where the built-in components reside are expanded.

Builder determines which tabs to display based on what role and permissions an Admin has assigned a user, so some users have more tabs available to them than others. For details on which tabs are available to which roles, visit Roles and Permissions in a Space.

For details on using these blocks in the Visual Editor, read Block Types in Builder, which covers the basics of the blocks UI.

Location in Visual Editor: Basics section of the Insert tab.

Builder.registerComponent(ButtonComponent, {
  name: 'Core:Button',
  defaultStyles: {
    appearance: 'none',
    paddingTop: '15px',
    paddingBottom: '15px',
    paddingLeft: '25px',
    paddingRight: '25px',
    backgroundColor: '#000000',
    color: 'white',
    borderRadius: '4px',
    textAlign: 'center',
    cursor: 'pointer',
  },
  inputs: [
    {
      name: 'text',
      type: 'text',
      defaultValue: 'Click me!',
      bubble: true,
    },
    {
      name: 'link',
      type: 'url',
      bubble: true,
    },
    {
      name: 'openLinkInNewTab',
      type: 'boolean',
      defaultValue: false,
      friendlyName: 'Open link in new tab',
    },
  ],
  noWrap: true,
});

Location in Visual Editor: Basics section of the Insert tab.

Builder.registerComponent(ColumnsComponent, {
  name: 'Columns',
  static: true,
  inputs: [
    {
      name: 'columns',
      type: 'array',
      broadcast: true,
      subFields: [
        {
          name: 'blocks',
          type: 'array',
          hideFromUI: true,
          defaultValue: defaultBlocks,
        },
        {
          name: 'width',
          type: 'number',
          hideFromUI: true,
          helperText: 'Width %, e.g. set to 50 to fill half of the space',
        },
        {
          name: 'link',
          type: 'url',
          helperText: 'Optionally set a url that clicking this column will link to',
        },
      ],
      defaultValue: [{ blocks: defaultBlocks }, { blocks: defaultBlocks }],
    },
    {
      name: 'space',
      type: 'number',
      defaultValue: 20,
      helperText: 'Size of gap between columns',
      advanced: true,
    },
    {
      name: 'stackColumnsAt',
      type: 'string',
      defaultValue: 'tablet',
      helperText: 'Convert horizontal columns to vertical at what device size',
      enum: ['tablet', 'mobile', 'never'],
      advanced: true,
    },
    {
      name: 'reverseColumnsWhenStacked',
      type: 'boolean',
      defaultValue: false,
      helperText: 'When stacking columns for mobile devices, reverse the ordering',
      advanced: true,
    },
  ],
});

Location in Visual Editor: Code section of the Insert tab.

Builder.registerComponent(CustomCodeComponent, {
  name: 'Custom Code',
  static: true,
  requiredPermissions: ['editCode'],
  inputs: [
    {
      name: 'code',
      type: 'html',
      required: true,
      defaultValue: '<p>Hello there, I am custom HTML code!</p>',
      code: true,
    },
    {
      name: 'replaceNodes',
      type: 'boolean',
      helperText: 'Preserve server rendered dom nodes',
      advanced: true,
    },
    {
      name: 'scriptsClientOnly',
      type: 'boolean',
      helperText:
        'Only print and run scripts on the client. Important when scripts influence DOM that could be replaced when client loads',
      advanced: true,
    },
  ],
});

Location in Visual Editor: Media section of the Insert tab.

Builder.regsterComponent(EmbedComponent, {
  name: 'Embed',
  static: true,
  inputs: [
    {
      name: 'url',
      type: 'url',
      required: true,
      defaultValue: '',
      helperText: 'e.g. enter a youtube url, google map, etc',
    },
    {
      name: 'content',
      type: 'html',
      defaultValue: `<div style="padding: 20px; text-align: center">(Choose an embed URL)<div>`,
      hideFromUI: true,
    },
  ],
});

Location in Visual Editor: Basics section of the Insert tab.

Builder.registerComponent(ImageComponent, {
  name: 'Image',
  defaultStyles: {
    position: 'relative',
    minHeight: '20px',
    minWidth: '20px',
    overflow: 'hidden',
  },
  canHaveChildren: true,
  inputs: [
    {
      name: 'image',
      type: 'file',
      bubble: true,
      allowedFileTypes: ['jpeg', 'jpg', 'png', 'svg'],
      required: true,
    },
    {
      name: 'backgroundSize',
      type: 'text',
      defaultValue: 'cover',
      enum: [
        {
          label: 'contain',
          value: 'contain',
          helperText: 'The image should never get cropped',
        },
        {
          label: 'cover',
          value: 'cover',
          helperText: `The image should fill its box, cropping when needed`,
        },
      ],
    },
    {
      name: 'backgroundPosition',
      type: 'text',
      defaultValue: 'center',
      enum: [
        'center',
        'top',
        'left',
        'right',
        'bottom',
        'top left',
        'top right',
        'bottom left',
        'bottom right',
      ],
    },
    {
      name: 'altText',
      type: 'string',
      helperText: 'Text to display when the user has images off',
    },
    {
      name: 'height',
      type: 'number',
      hideFromUI: true,
    },
    {
      name: 'width',
      type: 'number',
      hideFromUI: true,
    },
    {
      name: 'sizes',
      type: 'string',
      hideFromUI: true,
    },
    {
      name: 'srcset',
      type: 'string',
      hideFromUI: true,
    },
    {
      name: 'lazy',
      type: 'boolean',
      defaultValue: true,
      hideFromUI: true,
    },
    {
      name: 'fitContent',
      type: 'boolean',
      helperText:
        "When child blocks are provided, fit to them instead of using the image's aspect ratio",
      defaultValue: true,
    },
    {
      name: 'aspectRatio',
      type: 'number',
      helperText:
        "This is the ratio of height/width...",
      advanced: true,
      defaultValue: DEFAULT_ASPECT_RATIO,
    },
  ],
});

Location in Visual Editor: Basics section of the Insert tab.

Builder.registerComponent(SectionComponent, {
  name: 'Core:Section',
  inputs: [
    {
      name: 'maxWidth',
      type: 'number',
      defaultValue: 1200,
    },
    {
      name: 'lazyLoad',
      type: 'boolean',
      defaultValue: false,
      advanced: true,
      description: 'Only render this section when in view',
    },
  ],
  defaultStyles: {
    paddingLeft: '20px',
    paddingRight: '20px',
    paddingTop: '50px',
    paddingBottom: '50px',
    marginTop: '0px',
    width: '100vw',
    marginLeft: 'calc(50% - 50vw)',
  },
  canHaveChildren: true,

  defaultChildren: [
    {
      '@type': '@builder.io/sdk:Element',
      responsiveStyles: {
        large: {
          textAlign: 'center',
        },
      },
      component: {
        name: 'Text',
        options: {
          text: "<p>I am a section!</p>",
        },
      },
    },
  ],
});

Location in Visual Editor: Code section of the Insert tab.

Builder.registerComponent(Slot, {
  name: 'Slot',
  description: 'Allow child blocks within this content when used as a Symbol',
  inputs: [{ 
    name: 'name', 
    type: 'string', 
    required: true, 
    defaultValue: 'children' 
  }],
});

Location in Visual Editor: Code section of the Insert tab.

Builder.registerComponent(SymbolComponent, {
  name: 'Symbol',
  noWrap: true,
  inputs: [
    {
      name: 'symbol',
      type: 'uiSymbol',
    },
    {
      name: 'dataOnly',
      helperText: `Make this a data symbol that doesn't display any UI`,
      type: 'boolean',
      defaultValue: false,
      advanced: true,
      hideFromUI: true,
    },
    {
      name: 'inheritState',
      helperText: `Inherit the parent component state and data`,
      type: 'boolean',
      defaultValue: isShopify,
      advanced: true,
    },
    {
      name: 'renderToLiquid',
      helperText: 'Render this symbols contents to liquid...',
      type: 'boolean',
      defaultValue: isShopify,
      advanced: true,
      hideFromUI: true,
    },
    {
      name: 'useChildren',
      hideFromUI: true,
      type: 'boolean',
    },
  ],
});

Location in Visual Editor: Basics section of the Insert tab.

Builder.registerComponent(TextComponent, {
  name: 'Text',
  static: true,
  image: iconUrl,
  inputs: [
    {
      name: 'text',
      type: 'html',
      required: true,
      autoFocus: true,
      bubble: true,
      defaultValue: 'Enter some text...',
    },
  ],
  defaultStyles: {
    lineHeight: 'normal',
    height: 'auto',
    textAlign: 'center',
  },
});

Location in Visual Editor: Media section of the Insert tab.

Builder.registerComponent(withChildren(VideoComponent), {
  name: 'Video',
  canHaveChildren: true,
  defaultStyles: {
    minHeight: '20px',
    minWidth: '20px',
  },
  inputs: [
    {
      name: 'video',
      type: 'file',
      allowedFileTypes: ['mp4'],
      bubble: true,
      required: true,
    },
    {
      name: 'posterImage',
      type: 'file',
      allowedFileTypes: ['jpeg', 'png'],
      helperText: 'Image to show before the video plays',
    },
    {
      name: 'autoPlay',
      type: 'boolean',
      defaultValue: true,
    },
    {
      name: 'controls',
      type: 'boolean',
      defaultValue: false,
    },
    {
      name: 'muted',
      type: 'boolean',
      defaultValue: true,
    },
    {
      name: 'loop',
      type: 'boolean',
      defaultValue: true,
    },
    {
      name: 'playsInline',
      type: 'boolean',
      defaultValue: true,
    },
    {
      name: 'fit',
      type: 'text',
      defaultValue: 'cover',
      enum: ['contain', 'cover', 'fill', 'auto'],
    },
    {
      name: 'preload',
      type: 'text',
      defaultValue: 'metadata',
      enum: ['auto', 'metadata', 'none'],
    },
    {
      name: 'fitContent',
      type: 'boolean',
      helperText: 'Fit to child blocks instead of using the aspect ratio',
      defaultValue: true,
      advanced: true,
    },
    {
      name: 'position',
      type: 'text',
      defaultValue: 'center',
      enum: [
        'center',
        'top',
        'left',
        'right',
        'bottom',
        'top left',
        'top right',
        'bottom left',
        'bottom right',
      ],
    },
    {
      name: 'height',
      type: 'number',
      advanced: true,
    },
    {
      name: 'width',
      type: 'number',
      advanced: true,
    },
    {
      name: 'aspectRatio',
      type: 'number',
      advanced: true,
      defaultValue: DEFAULT_ASPECT_RATIO,
    },
    {
      name: 'lazyLoad',
      type: 'boolean',
      helperText:
        'Load this video lazily',
      defaultValue: true,
      advanced: true,
    },
  ],
});

If you'd like to exclusively use your own components in your Builder Space, read Components-only Mode.

For the source code, visit Builder's GitHub repo.

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