Editor
The main editor instance. Use it for lifecycle events, managers, and command execution.
This guide focuses on practical implementation: strict typing for editor lifecycle, plugin contracts, and custom component definitions your team can maintain long-term.
Type source
Built-in v1.x
Recommended mode
strict: true
Use case
Prod editors
The main editor instance. Use it for lifecycle events, managers, and command execution.
Represents a node in the canvas tree. Useful for typed event handlers and custom traits.
A draggable building block. Type-safe block definitions reduce runtime content mistakes.
Used when registering new component types through ComponentManager.addType().
Strongly types defaults and traits so team members reuse the same component contract.
Covers storage config and operations for local or remote persistence workflows.
Step 01
Enable strict mode and noImplicitAny before writing editor logic to catch plugin and component mistakes early.
Step 02
Use Editor | null for initialization flow and add guards before calling manager APIs from async callbacks.
Step 03
Define option interfaces with defaults so plugin APIs stay stable across projects and versions.
Step 04
Standardize component traits and defaults with shared TypeScript types to keep teams aligned.
Keep editor initialization and event flow typed from day one. This catches invalid manager calls and event payload errors early.
import grapesjs from 'grapesjs';
import type { Editor, Component, Block } from 'grapesjs';
// Typed editor instance
let editor: Editor | null = null;
editor = grapesjs.init({
container: '#gjs',
storageManager: false,
});
// Typed event handlers
editor.on('component:add', (component: Component) => {
console.log('Added component:', component.get('type'));
});
// Typed block access
const blockManager = editor.BlockManager;
const blocks: Block[] = blockManager.getAll().models;Define plugin option interfaces and defaults to make your extension safe for teams and predictable across releases.
import type { Editor } from 'grapesjs';
interface MyPluginOptions {
apiKey?: string;
debug?: boolean;
}
const myPlugin = (editor: Editor, opts: MyPluginOptions = {}) => {
const { apiKey = '', debug = false } = opts;
editor.BlockManager.add('custom-block', {
label: 'Custom Block',
category: 'Custom',
content: '<div class="custom-block">Custom content</div>',
});
if (debug) {
console.log('Plugin initialized with API key:', apiKey);
}
};
export default myPlugin;Typed component definitions reduce runtime trait errors and help product teams create reusable content models.
import type { ComponentDefinition, ComponentProperties } from 'grapesjs';
// Typed component definition
const heroComponent: ComponentDefinition = {
model: {
defaults: {
tagName: 'section',
draggable: true,
droppable: false,
attributes: { class: 'hero-section' },
traits: [
{ type: 'text', name: 'headline', label: 'Headline' },
{ type: 'text', name: 'subheadline', label: 'Subheadline' },
],
} as ComponentProperties,
},
};
editor.ComponentManager.addType('hero', heroComponent);All premium plugins include TypeScript definitions for safer and faster integration.
Browse plugins