Made in Builder

Made in

How to Build: Localization webinar on March 23rd @ 10am PST. Register Now




Use Cases





Log in




Talk to an Expert











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



Get StartedLogin

To use your custom components in the Builder Visual Editor, you need to take a couple of minimal steps in your codebase.

To get the most our of this tutorial, you should have the following:

  • Integrated Pages or Sections
  • The Builder SDK installed for your framework

Tip: This tutorial is for custom components in all Builder's supported frameworks except for the HTML API.

Setting up your code

To use your custom component with Builder, you need to let Builder know about it by registering your component. Registering your component makes the component appear in the Visual Editor as a custom block. Follow the steps according to framework.

Now your component should show up in the Visual Editor with no further configuration in the code.

The following video shows the Custom Thing block in the Custom Components section of the Insert tab.

CustomThing has an input registered with Builder called name. To use a registered component's input, do the following:

  1. Drag and drop your custom component into the work area.
  2. Select your component by clicking on it.
  3. Click the Edit button.
  4. Add a value for the the input, in this example, the input is called name, and the value added is the text, "Sunshine".

When you register a component, you must provide a name. Optionally, you can also specify:

  • component default styling
  • whether Builder wraps the component in a <div>
  • whether the component displays in the Insert tab

The following table describes each of the additional component options:




Use for showing an example value in the input form when creating a new instance of this component, to users understand its purpose. Users in the Visual Editor can edit these styles.

Builder.registerComponent(HelloWorldComponent, {
  defaultStyles: {
    textAlign: "center",
    fontSize: "20px",



Hide your component from the Insert tab within Builder's Visual Editor. Use this feature for deprecating a component when you want to reduce its use, but still need the component registered with Builder so that older content that uses the component continues to function properly. For more information on versioning, refer to Versioning Custom Components.

hideFromInsertMenu: true



By default, Builder wraps your components in a <div>.

You can opt out of this wrapping by using the noWrap option. For a full code example, see Builder's built-in form input component.

The following example shows noWrap with a Material UI TextField in

Tip: When using noWrap: true, it is important to pass {...props.attributes} to ensure class names are assigned correctly as in the following example.

import { TextField } from '@material-ui/core'

export const BuilderTextField = props => (
  // Important! must add a couple classes 
  // and attributes via props.attributes
  // Important! If you add your own classes, 
  // do it after ...props.attributes 
    className={`my-class ${props.attributes.className}`}

Builder.registerComponent(BuilderTextField, {
  name: 'TextField',
  noWrap: true, // Important!
  inputs: [{ name: 'variant', type: 'string' }]

The following code snippet features all component options in the context of registerComponent():

const HeloWorldComponent = (props) => <div>{props.text}</div>;

Builder.registerComponent(HelloWorldComponent, {
  // Begin component options
  // Name your component (required)
  name: "Hello World",
  // Optional: provide CSS in an object to defaultStyles
  defaultStyles: {
    textAlign: "center",
    fontSize: "20px",
  // Optional: specify whether your component is wrapped in a <div>
  noWrap: true,
  // Optional: specify if your component shows in the Insert tab
  hideFromInsertMenu: false,
  // End component options

  // Begin inputs:  
  inputs: [{ ... }],

You can programmatically set bindings on custom components so you can apply multiple bindings simultaneously. This is helpful when, for example, applying styles from an existing design system. The snippet below registers a custom component with default bindings for the product title and a theme background color:

 Builder.registerComponent(MyComponent, {
    name: 'MyComponent',
    defaults: {
      bindings: {
        'component.options.title': 'state.product.title',
        'style.background': 'state.theme.colors.primary'

Unless you're using a React-based framework, your components can fetch data async out-of-the-box.

If you are using a React-based framework and want your component to fetch data async, use Builder's getAsyncProps helper.

In the following example, the page loads after the all the data arrives:

export async function getStaticProps(context) {
  const content = await builder.get('page', { url: context.resolvedUrl }).promise();

  await getAsyncProps(content, {
    async Products(props) {
      return {
        data: await fetch(`${apiRoot}/products?cat=${props.category}`).then(res => res.json()),

  return { props: { content } };

For more information about getAsyncProps see the Builder Utils README on GitHub.

To control exactly which models your component is available in, use the models array when registering your component as in the following example:

Builder.registerComponent(RelatedProducts, {
  name: 'RelatedProducts',
  models: ['product-editorial', 'page'],

In this example, the RelatedProducts component is only accessible in the Visual Editor when editing content entries made with the product-editorial or page models.

To learn how to test and customize how your component appears in the Visual Editor, continue on to Using Your Custom Components in the Visual Editor.

To limit visual editing to only your custom components, use Components-only mode.

Looking to hire a 3rd party to help with your project?

Submit a project request and our partnerships team will reach out to connect you with an Expert from our partner ecosystem.

Connect with us

Was this article helpful?