BUILDER

Resources

×

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

☰

Home

Forum

Blog

Github

Login

Signup

This page was made in Builder!

Extending Builder with Plugins

While we put a lot of effort into making Builder come with great defaults, you can customize nearly every part of the CMS and editor using custom React code with our plugin system.

Possible examples include an image management plugin, a plugin to integrate with Shopify, or a plugin to customize the look and feel of the Builder editor.

👉Tip: If you want to dive in head first and start coding, jump over to our examples in Github to get hacking

What can you modify

With Builder plugins, there are two main customization areas. One if registering custom types, which are used in many places in the Builder UIs, and the other is to modify the editor UI itself

Custom type editors

Custom editor plugins allow you to register custom field types for your Builder model custom fields and inputs for your custom components, custom targeting or symbols.

They take simple react components that take a value and onChange prop. The value you set can be any type serializable to JSON (e.g. string, number, null, array, object, etc) and be as deeply nested as you need.

Plugins execute inside the Builder web application, so they need to be developed separately from your web application. See the example plugin for instructions on how to build, deploy, and connect your plugin to your Builder.io account.

Custom Editor

Usage

import { Builder } from '@builder.io/sdk';
import ReactQuill from 'react-quill';

function RichTextEditor(props) {
  return (
    <ReactQuill
      theme="snow"
      value={props.value}
      onChange={props.onChange}
      modules={/* your custom options */}
    />
  );
}

Builder.registerEditor({
  name: 'myRichText',
  component: RichTextEditor,
});

Modifying the editor and CMS

Below are some of the possible parts of the editor that you are able to modify via Builder.register(<some-key>) .

👉Tip: See our campaign plugin example for a kitchen sink app highlighting nearly all of the features below

LocationExample

appTab

Make an app-wide tab that displays and edits content in unique ways using our read and write APIs

E.g. make a content calendar that allows you to view your scheduled content on a calendar showing when content will go live when, and allow the user to drag to reschedule

import { Builder } from '@builder.io/react';

function CalendarView(props) {
  return <>{/* Read content and display on a calendar */}</>;
}

Builder.register('appTab', {
  name: 'Calendar',
  path: 'calendar',
  icon:  'https:/...',
  component: CalendarView,
})

editor.mainTab

Add a new tab located at the top of the preview window to view or edit the current document

E.g. create a notes tab that let's people post and view notes to collaborate

import { Builder } from '@builder.io/react';
import { useObserver } from 'mobx-react'
const context = require('@builder.io/app-context').default;

function NotesTab(props) {
  const { data } = context.designerState.editingContentModel;
  return useObserver(() =>
    <textarea 
      value={data.get('notes')} 
      onChange={e => data.set('notes', e.target.value)} /> 
  );
}

Builder.register('editor.mainTab', {
  name: 'Notes',
  component: NotesTab,
})

editor.editTab

Add a new tab located on the left sidebar to edit the currently selected element(s)

E.g. create a Tailwind UI tab that applies tailwind classes to elements

import { Builder } from '@builder.io/react';
import { useObserver } from 'mobx-react'
const context = require('@builder.io/app-context').default;

function TailwindTab(props) {
  const { selection } = context.designerState;
  return useObserver(() => 
    <input title="color" type="number" onChange={e => {
      selection.forEach(el => {
        let value = e.target.value;
        el.properties.set('class', `text-gray-${value}`)
      })
     } />
  );
}

Builder.register('editor.editTab', {
  name: 'Tailwind',
  component: TailwindTab,
})

editor.insertMenu

Override the insert menu displaying components you can drop in custom

import { Builder } from '@builder.io/react';
const { designerState } = require('@builder.io/app-context').default;

function InsertTab(props) {
  return <>
    <div 
      onClick={() => 
        designerState.draggingInItem = 'Custom component 1' 
      } />
    <div 
      onClick={() => 
        designerState.draggingInItem = 'Custom component 2' 
      } />
  </>
}

Builder.register('editor.insertTab', {
  component: InsertTab,
})

editor.toolbarButton

Add a toolbar button

E.g. create a workflow status button for custom workflows

import { Builder } from '@builder.io/react';
const { designerState } = require('@builder.io/app-context').default;

function WorkflowButton(props) {
  return <div onClick={launchApprovalModal}>
     Pending approval
  </div>
}

Builder.register('editor.toolbarButton', {
  component: WorkflowButton,
})

Editor settings

You can also update various editor settings:

import { Builder } from '@builder.io/builder'

Builder.register('editor.settings', {
  hideStyleTab: false,      // Hide the style tab
  hideMainTabs: false,      // Hide all main tabs
  hideDataTab: false ,      // Hide the data tab
  hideOptionsTab: false,    // Hide the options tab
  hideToolbar: false,       // Hide the main toolbar
  hideHeatMap: false,       // Hide the heatmap button
  hidePageUrlEditor: false, // Hide the page URL editor
  hideAnimateTab: false,    // Hide the animate tab
  hideInsertTab: false,     // Hide the insert tab
  hideTargeting: false,     // Hide the targeting UI
})

App Context

You may notice the example above, and our open source examples, use this. It gives access to application state, including the current editing document, API access, etc.

See here for docs and type definitions for what is available in app state.

Was this article helpful?