Editor.js provides extensive configuration options to customize editor behavior, appearance, and functionality. The EditorConfig interface allows fine-grained control over every aspect of the editor.
Core settings for initializing the editor.
interface EditorConfig {
/**
* Element where editor will be appended
*/
holder?: string | HTMLElement;
/**
* Deprecated: use holder instead
*/
holderId?: string | HTMLElement;
/**
* Focus editor on first block after initialization
*/
autofocus?: boolean;
/**
* Default tool for new blocks
*/
defaultBlock?: string;
/**
* Deprecated: use defaultBlock instead
*/
initialBlock?: string;
/**
* Placeholder text for empty editor
*/
placeholder?: string | false;
}Usage Examples:
// Basic configuration
const editor = new EditorJS({
holder: 'editorjs', // Element ID
autofocus: true,
defaultBlock: 'paragraph',
placeholder: 'Start writing your story...'
});
// Using DOM element reference
const holderElement = document.getElementById('my-editor');
const editor = new EditorJS({
holder: holderElement,
autofocus: false,
placeholder: false // Disable placeholder
});
// Configuration with multiple options
const editor = new EditorJS({
holder: 'editorjs',
autofocus: true,
defaultBlock: 'header', // New blocks will be headers by default
placeholder: 'Enter your title here...'
});Settings for configuring available tools and their behavior.
interface EditorConfig {
/**
* Map of available tools
*/
tools?: {
[toolName: string]: ToolConstructable | ToolSettings;
};
/**
* Default inline toolbar tools for all blocks
*/
inlineToolbar?: string[] | boolean;
/**
* Common block tunes applied to all blocks
*/
tunes?: string[];
}
interface ToolSettings {
class: ToolConstructable;
config?: ToolConfig;
inlineToolbar?: string[] | boolean;
tunes?: string[];
shortcut?: string;
}Usage Examples:
import Header from '@editorjs/header';
import Paragraph from '@editorjs/paragraph';
import List from '@editorjs/list';
const editor = new EditorJS({
tools: {
// Simple tool registration
header: Header,
// Tool with configuration
paragraph: {
class: Paragraph,
config: {
placeholder: 'Type your paragraph here...'
},
inlineToolbar: ['bold', 'italic', 'link']
},
// Tool with tunes and shortcut
list: {
class: List,
config: {
defaultStyle: 'unordered'
},
tunes: ['textAlignment'],
shortcut: 'CMD+SHIFT+L'
}
},
// Default inline toolbar for all tools
inlineToolbar: ['bold', 'italic', 'link'],
// Common tunes for all blocks
tunes: ['textAlignment', 'anchor']
});Settings for initial content and data handling.
interface EditorConfig {
/**
* Initial data to render in editor
*/
data?: OutputData;
/**
* HTML sanitization configuration
*/
sanitizer?: SanitizerConfig;
}Usage Examples:
// Editor with initial content
const editor = new EditorJS({
data: {
version: "2.30.8",
time: Date.now(),
blocks: [
{
type: "header",
data: {
text: "Welcome to My Blog",
level: 1
}
},
{
type: "paragraph",
data: {
text: "This is the first paragraph of content."
}
}
]
}
});
// Custom sanitization rules
const editor = new EditorJS({
sanitizer: {
b: true,
i: true,
u: true,
s: true,
p: {
class: 'custom-paragraph'
},
a: {
href: true,
target: '_blank'
}
}
});Settings that control editor behavior and functionality.
interface EditorConfig {
/**
* Enable read-only mode
*/
readOnly?: boolean;
/**
* Hide the toolbar completely
*/
hideToolbar?: boolean;
/**
* Minimum height of editor area
*/
minHeight?: number;
/**
* Logging level for debugging
*/
logLevel?: LogLevels;
}
type LogLevels = 'VERBOSE' | 'INFO' | 'WARN' | 'ERROR';Usage Examples:
// Read-only editor for displaying content
const readOnlyEditor = new EditorJS({
holder: 'display-area',
readOnly: true,
hideToolbar: true,
data: existingContent
});
// Editor with custom behavior
const editor = new EditorJS({
holder: 'editorjs',
minHeight: 300, // Minimum 300px height
logLevel: 'WARN', // Only show warnings and errors
hideToolbar: false
});
// Development editor with verbose logging
const devEditor = new EditorJS({
holder: 'dev-editor',
logLevel: 'VERBOSE', // Show all debug information
minHeight: 500
});Callback functions for responding to editor events.
interface EditorConfig {
/**
* Called when editor is fully initialized
*/
onReady?(): void;
/**
* Called when editor content changes
*/
onChange?(api: API, event: BlockMutationEvent | BlockMutationEvent[]): void;
}Usage Examples:
const editor = new EditorJS({
onReady: () => {
console.log('Editor.js is ready to work!');
// Perform initialization tasks
loadDraftFromLocalStorage();
setupAutoSave();
},
onChange: (api, event) => {
console.log('Content changed:', event);
// Auto-save functionality
clearTimeout(autoSaveTimer);
autoSaveTimer = setTimeout(async () => {
const data = await api.saver.save();
localStorage.setItem('editor-content', JSON.stringify(data));
}, 2000);
// Track changes for analytics
if (Array.isArray(event)) {
event.forEach(e => trackChange(e));
} else {
trackChange(event);
}
}
});Settings for multi-language support.
interface EditorConfig {
/**
* Internationalization configuration
*/
i18n?: I18nConfig;
}
interface I18nConfig {
/**
* Current language direction
*/
direction?: 'ltr' | 'rtl';
/**
* Translation messages
*/
messages?: I18nDictionary;
}
interface I18nDictionary {
ui?: Dictionary;
toolNames?: Dictionary;
tools?: Dictionary;
blockTunes?: Dictionary;
}Usage Examples:
// Arabic/RTL configuration
const arabicEditor = new EditorJS({
i18n: {
direction: 'rtl',
messages: {
ui: {
'blockTunes.delete.confirm': 'هل أنت متأكد؟',
'toolbar.toolbox.add': 'إضافة'
},
toolNames: {
'paragraph': 'فقرة',
'header': 'عنوان'
}
}
}
});
// Custom English messages
const customEditor = new EditorJS({
i18n: {
messages: {
ui: {
'blockTunes.delete.confirm': 'Are you sure you want to delete this block?',
'toolbar.toolbox.add': 'Add new block'
},
toolNames: {
'paragraph': 'Text Block',
'header': 'Heading'
}
}
}
});Settings for custom styling and security.
interface EditorConfig {
/**
* Style-related configuration
*/
style?: {
/**
* Nonce for Content Security Policy
*/
nonce?: string;
};
}Usage Examples:
// CSP-compliant configuration
const secureEditor = new EditorJS({
holder: 'secure-editor',
style: {
nonce: 'random-nonce-value-123' // For CSP style-src policy
}
});// Comprehensive editor configuration
const editor = new EditorJS({
// Basic setup
holder: 'editorjs',
autofocus: true,
defaultBlock: 'paragraph',
placeholder: 'Tell your story...',
// Tools configuration
tools: {
header: {
class: Header,
config: {
levels: [1, 2, 3, 4],
defaultLevel: 2
},
inlineToolbar: ['bold', 'italic'],
tunes: ['textAlignment']
},
paragraph: {
class: Paragraph,
config: {
placeholder: 'Enter your text here...'
},
inlineToolbar: true
},
list: {
class: List,
inlineToolbar: true,
tunes: ['textAlignment']
},
quote: {
class: Quote,
config: {
quotePlaceholder: 'Enter a quote',
captionPlaceholder: 'Quote author'
}
}
},
// Global settings
inlineToolbar: ['bold', 'italic', 'link'],
tunes: ['textAlignment'],
// Behavior
readOnly: false,
minHeight: 400,
logLevel: 'WARN',
// Initial content
data: {
blocks: [
{
type: 'header',
data: {
text: 'Welcome!',
level: 1
}
}
]
},
// Event handlers
onReady: () => {
console.log('Editor is ready');
},
onChange: (api, event) => {
console.log('Content changed');
},
// Internationalization
i18n: {
direction: 'ltr',
messages: {
ui: {
'blockTunes.delete.confirm': 'Delete this block?'
}
}
},
// Security
style: {
nonce: generateNonce()
}
});Editor.js validates configuration and provides helpful error messages:
Usage Examples:
try {
const editor = new EditorJS({
holder: 'non-existent-element', // This will throw an error
tools: {
invalidTool: 'not-a-constructor' // This will also cause issues
}
});
} catch (error) {
console.error('Configuration error:', error.message);
// Handle configuration errors gracefully
const fallbackEditor = new EditorJS({
holder: 'fallback-container',
tools: {} // Minimal safe configuration
});
}interface EditorConfig {
holder?: string | HTMLElement;
holderId?: string | HTMLElement;
autofocus?: boolean;
defaultBlock?: string;
initialBlock?: string;
placeholder?: string | false;
sanitizer?: SanitizerConfig;
hideToolbar?: boolean;
tools?: {[toolName: string]: ToolConstructable | ToolSettings};
data?: OutputData;
minHeight?: number;
logLevel?: LogLevels;
readOnly?: boolean;
i18n?: I18nConfig;
onReady?(): void;
onChange?(api: API, event: BlockMutationEvent | BlockMutationEvent[]): void;
inlineToolbar?: string[] | boolean;
tunes?: string[];
style?: { nonce?: string };
}
interface ToolSettings {
class: ToolConstructable;
config?: ToolConfig;
inlineToolbar?: string[] | boolean;
tunes?: string[];
shortcut?: string;
}
interface SanitizerConfig {
[tagName: string]: boolean | {
[attrName: string]: boolean | string;
};
}
type LogLevels = 'VERBOSE' | 'INFO' | 'WARN' | 'ERROR';