Building a Custom Display Block
In NocoBase, blocks are content areas on a page. This example demonstrates how to build the simplest custom block using BlockModel -- supporting HTML content editing through the UI, allowing users to modify the block's displayed content via a configuration panel.
This is the first example involving FlowEngine, using BlockModel, renderComponent, registerFlow, and uiSchema.
It's recommended to familiarize yourself with the following content for a smoother development experience:
- Writing Your First Plugin -- Plugin creation and directory structure
- Plugin -- Plugin entry point and
load()lifecycle - FlowEngine Overview -- FlowModel, renderComponent, registerFlow basic usage
- i18n Internationalization -- Translation file conventions and
tExpr()deferred translation usage
Final Result
We're building a "Simple block":
- Appears in the "Add Block" menu
- Renders user-configured HTML content
- Allows users to edit HTML through a configuration panel (registerFlow + uiSchema)
Full source code is available at @nocobase-example/plugin-simple-block. If you want to run it locally:
Let's build this plugin step by step from scratch.
Step 1: Create the Plugin Skeleton
Run the following in the repository root:
This will generate a basic file structure under packages/plugins/@my-project/plugin-simple-block. For detailed instructions, see Writing Your First Plugin.
Step 2: Create the Block Model
Create src/client-v2/models/SimpleBlockModel.tsx. This is the core of the entire plugin -- defining how the block renders and how it's configured.
Key points:
renderComponent()-- Renders the block UI, reading HTML content viathis.props.htmldefine()-- Sets the display name in the "Add Block" menu.tExpr()is used for deferred translation becausedefine()executes at module load time, when i18n hasn't been initialized yetregisterFlow()-- Adds a configuration panel.uiSchemadefines the form using JSON Schema (syntax reference: UI Schema),handlerwrites user-filled values toctx.model.props, andrenderComponent()can read them
Step 3: Add Multilingual Files
Edit the translation files under the plugin's src/locale/, adding translations for all keys used by tExpr():
Adding language files for the first time requires restarting the application to take effect.
For more about translation file conventions and tExpr() usage, see i18n Internationalization.
Step 4: Register in the Plugin
Edit src/client-v2/plugin.tsx to lazy-load the model via registerModelLoaders:
registerModelLoaders uses dynamic imports so that model code is only loaded when actually needed -- this is the recommended registration approach.
Step 5: Enable the Plugin
After enabling, create a new page and click "Add Block" to see "Simple block". Once added, click the block's configuration button to edit the HTML content.
Full Source Code
- @nocobase-example/plugin-simple-block -- Complete custom display block example
Summary
Capabilities used in this example:
Related Links
- Writing Your First Plugin -- Create a plugin skeleton from scratch
- FlowEngine Overview -- FlowModel basic usage and registerFlow
- FlowEngine -> Block Extension -- BlockModel, DataBlockModel, CollectionBlockModel
- UI Schema -- uiSchema syntax reference
- Component vs FlowModel -- When to use FlowModel
- Plugin -- Plugin entry point and load() lifecycle
- i18n Internationalization -- Translation file conventions and tExpr usage
- FlowEngine Complete Documentation -- Complete reference for FlowModel, Flow, Context

