Advanced customization

Blockly lets you customize certain functionality by replacing the corresponding Blockly classes.

Replaceable classes

The following Blockly classes can be replaced:

Blockly class Interface Registration name(s)
Blockly.dragging.Dragger Blockly.IDragger blockDragger
Blockly.ConnectionChecker Blockly.IConnectionChecker connectionChecker
Blockly.InsertionMarkerPreviewer Blockly.IConnectionPreviewer connectionPreviewer
Blockly.Flyout Blockly.IFlyout flyoutsVerticalToolbox
flyoutsHorizontalToolbox
Blockly.MetricsManager Blockly.IMetricsManager metricsManager
Blockly.blockRendering.Renderer* -- renderer
Blockly.Toolbox Blockly.IToolbox toolbox

* This is the base class for all renderers. You can subclass it or an existing renderer. See Create a new renderer.

Blockly's interfaces are defined in core/interfaces.

Create a replacement class

To create a replacement class, implement the functions in the corresponding interface. You can implement all of these functions in a new class, or extend the Blockly class and only override the functions you want to change. The only requirement is that you (or the base class) implement all of the functions in the interface and adhere to any requirements described in comments on the interface.

To indicate to the type checker that you implement a specific interface, annotate your class with the @implements {InterfaceName} JSDoc tag (in JavaScript) or the implements keyword (in TypeScript).

Inject your replacement class

To tell Blockly about your replacement class, use the plugins property in the BlocklyOptions object passed to Blockly.inject. (In spite of this property's name, your class does not need to be packaged and distributed through npm like the plugins used to extend Blockly.)

You can pass your subclass into the inject method.

Blockly.inject('blocklyDiv', {
  plugins: {
    'metricsManager': CustomMetricsManagerClass
  }
}

Or you can register your class using Blockly.registry and use the registry name to inject the class. This is useful if you store your injection options as pure JSON.

Blockly.registry.register(Blockly.registry.Type.METRICS_MANAGER, 'YOUR_NAME', SubClass);

Blockly.inject('blocklyDiv', {
  plugins: {
    'metricsManager': 'YOUR_NAME'
  }
}