### Install and Configure Marker Tool
Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md
Install the marker plugin to highlight text.
```bash
npm i @editorjs/marker
```
```javascript
marker: { class: Marker, shortcut: 'CMD+SHIFT+M' }
```
--------------------------------
### Install and Configure Underline Tool
Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md
Install the underline plugin to underline text.
```bash
npm i @editorjs/underline
```
```javascript
underline: { class: Underline, shortcut: 'CMD+U' }
```
--------------------------------
### Install and Configure Warning Tool
Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md
Install the warning plugin and add it to the Editor.js configuration.
```bash
npm i @editorjs/warning
```
```javascript
warning: {
class: Warning,
inlineToolbar: true,
config: { titlePlaceholder: 'Title', messagePlaceholder: 'Message' }
}
```
--------------------------------
### Install and Configure Table Tool
Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md
Install the table plugin and configure rows, columns, and headings.
```bash
npm i @editorjs/table
```
```javascript
table: {
class: Table,
inlineToolbar: true,
config: { rows: 2, cols: 3, withHeadings: true }
}
```
--------------------------------
### Install Warning Tool
Source: https://context7.com/schema31/editor-js-ai-skill/llms.txt
Install the Warning tool package via npm.
```bash
npm i @editorjs/warning
```
--------------------------------
### Install Code and Delimiter Tools
Source: https://context7.com/schema31/editor-js-ai-skill/llms.txt
Install the Code and Delimiter tool packages via npm.
```bash
npm i @editorjs/code @editorjs/delimiter
```
--------------------------------
### Install and Configure Simple Image Tool
Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md
Install the simple image plugin for base64 or direct URL storage without a backend.
```bash
npm i @editorjs/simple-image
```
```javascript
image: SimpleImage
```
--------------------------------
### Install Image Tool
Source: https://context7.com/schema31/editor-js-ai-skill/llms.txt
Install the Image tool package via npm.
```bash
npm i @editorjs/image
```
--------------------------------
### Install and Configure Delimiter Tool
Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md
Install the delimiter plugin and add it to the Editor.js configuration.
```bash
npm i @editorjs/delimiter
```
```javascript
delimiter: Delimiter
```
--------------------------------
### Install Embed Tool
Source: https://context7.com/schema31/editor-js-ai-skill/llms.txt
Install the Embed tool package via npm.
```bash
npm i @editorjs/embed
```
--------------------------------
### Install and Configure Embed Tool
Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md
Install the embed plugin and configure supported services or custom regex-based services.
```bash
npm i @editorjs/embed
```
```javascript
embed: {
class: Embed,
config: {
services: {
youtube: true, vimeo: true, codepen: true, github: true, twitter: true,
// Custom service
myService: {
regex: /https?:\/\/mysite\.com\/embed\/(.+)/,
embedUrl: 'https://mysite.com/embed/<%= remote_id %>',
html: '',
height: 300, width: 600
}
}
}
}
```
--------------------------------
### Install and Configure Quote Tool
Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md
Install the quote plugin and add it to the Editor.js configuration.
```bash
npm i @editorjs/quote
```
```javascript
quote: {
class: Quote,
inlineToolbar: true,
config: { quotePlaceholder: 'Enter a quote', captionPlaceholder: 'Quote author' }
}
```
--------------------------------
### Install and Configure Code Tool
Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md
Install the code plugin. Note that it enables line breaks by default.
```bash
npm i @editorjs/code
```
```javascript
code: { class: Code }
```
--------------------------------
### Install Inline Tools
Source: https://context7.com/schema31/editor-js-ai-skill/llms.txt
Install the Marker, Underline, and Inline Code tool packages via npm.
```bash
npm i @editorjs/marker @editorjs/underline @editorjs/inline-code
```
--------------------------------
### Install and Configure Header Tool
Source: https://context7.com/schema31/editor-js-ai-skill/llms.txt
Install the Header tool using npm. Configure it with inline toolbar, placeholder text, heading levels, and a default level.
```bash
npm i @editorjs/header
```
```javascript
import Header from '@editorjs/header';
const editor = new EditorJS({
tools: {
header: {
class: Header,
inlineToolbar: true,
config: {
placeholder: 'Enter a heading',
levels: [1, 2, 3, 4, 5, 6],
defaultLevel: 2
}
}
}
});
// Output: { "type": "header", "data": { "text": "My Heading", "level": 2 } }
```
--------------------------------
### Editor.js Decision Tree
Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md
A visual guide for navigating Editor.js setup and configuration tasks.
```text
Working with Editor.js?
├─ Setting up from scratch → Installation + Full Configuration
├─ Adding a content block → Official Block Tools
├─ Adding text formatting → Inline Tools (Marker, Underline, etc.)
├─ Block-level options → Block Tunes
├─ Building a custom block → Tools API (Custom Block Tool)
├─ Building a custom inline format → Tools API (Custom Inline Tool)
├─ Display content read-only → Read-Only Mode
├─ Multi-language support → i18n
├─ Rendering content on server → Server-Side Rendering (JS/PHP/Python)
├─ Framework integration → React / Vue / Vanilla JS examples
└─ TypeScript project → TypeScript Support section
```
--------------------------------
### Install editorjs-text-alignment-blocktune
Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md
Install the community plugin for block-level text alignment using npm.
```bash
npm i editorjs-text-alignment-blocktune
```
--------------------------------
### Install and Configure List Tool
Source: https://context7.com/schema31/editor-js-ai-skill/llms.txt
Install the List tool using npm. Configure it with an inline toolbar and a default list style (ordered or unordered).
```bash
npm i @editorjs/list
```
```javascript
import List from '@editorjs/list';
const editor = new EditorJS({
tools: {
list: {
class: List,
inlineToolbar: true,
config: { defaultStyle: 'unordered' }
}
}
});
// Output: { "type": "list", "data": { "style": "ordered", "items": ["First", "Second"] } }
```
--------------------------------
### Install editorjs-hyperlink
Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md
Install the community plugin for adding hyperlinks to content using npm.
```bash
npm i editorjs-hyperlink
```
--------------------------------
### Install Editor.js
Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md
Use npm to install the Editor.js package. This is the first step to integrating the editor into your project.
```bash
npm i @editorjs/editorjs --save
```
--------------------------------
### Install and Configure Raw HTML Tool
Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md
Install the raw HTML plugin and add it to the Editor.js configuration.
```bash
npm i @editorjs/raw
```
```javascript
raw: { class: Raw, config: { placeholder: 'Enter raw HTML' } }
```
--------------------------------
### Install and Configure Inline Code Tool
Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md
Install the inline code plugin to format text as code.
```bash
npm i @editorjs/inline-code
```
```javascript
inlineCode: { class: InlineCode, shortcut: 'CMD+SHIFT+C' }
```
--------------------------------
### Install editorjs-text-color-plugin
Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md
Install the community plugin for text coloring and background highlighting using npm.
```bash
npm i editorjs-text-color-plugin
```
--------------------------------
### Install and Configure Table Tool
Source: https://context7.com/schema31/editor-js-ai-skill/llms.txt
Install the Table tool using npm. Configure with inline toolbar, number of rows and columns, and option for a header row.
```bash
npm i @editorjs/table
```
```javascript
import Table from '@editorjs/table';
const editor = new EditorJS({
tools: {
table: {
class: Table,
inlineToolbar: true,
config: { rows: 2, cols: 3, withHeadings: true }
}
}
});
// Output:
// {
// "type": "table",
// "data": {
// "withHeadings": true,
// "content": [["Name", "Role"], ["Alice", "Engineer"]]
// }
// }
```
--------------------------------
### Install and Configure Image Tool
Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md
Install the image plugin. Supports custom uploader functions for file and URL uploads.
```bash
npm i @editorjs/image
```
```javascript
image: {
class: ImageTool,
config: {
endpoints: {
byFile: '/api/upload/image',
byUrl: '/api/fetch/url'
},
additionalRequestHeaders: { 'X-CSRF-Token': 'your-token' },
types: 'image/*',
// OR custom uploader:
uploader: {
uploadByFile(file) {
const formData = new FormData();
formData.append('image', file);
return fetch('/api/upload', { method: 'POST', body: formData })
.then(res => res.json())
.then(data => ({ success: 1, file: { url: data.url } }));
},
uploadByUrl(url) {
return fetch('/api/fetch-url', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ url })
})
.then(res => res.json())
.then(data => ({ success: 1, file: { url: data.url } }));
}
}
}
}
```
--------------------------------
### Install editorjs-annotation
Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md
Install the community plugin for adding annotations or notes to content using npm.
```bash
npm i editorjs-annotation
```
--------------------------------
### Install editorjs-change-case
Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md
Install the community plugin for changing the case of text content using npm.
```bash
npm i editorjs-change-case
```
--------------------------------
### Install and Configure Quote Tool
Source: https://context7.com/schema31/editor-js-ai-skill/llms.txt
Install the Quote tool using npm. Configure with inline toolbar and placeholders for quote text and author caption.
```bash
npm i @editorjs/quote
```
```javascript
import Quote from '@editorjs/quote';
const editor = new EditorJS({
tools: {
quote: {
class: Quote,
inlineToolbar: true,
config: {
quotePlaceholder: 'Enter a quote',
captionPlaceholder: 'Quote author'
}
}
}
});
// Output: { "type": "quote", "data": { "text": "...", "caption": "Author", "alignment": "left" } }
```
--------------------------------
### Install and Configure Checklist Tool
Source: https://context7.com/schema31/editor-js-ai-skill/llms.txt
Install the Checklist tool using npm. Enable inline toolbar for interactive checkbox lists.
```bash
npm i @editorjs/checklist
```
```javascript
import Checklist from '@editorjs/checklist';
const editor = new EditorJS({
tools: {
checklist: { class: Checklist, inlineToolbar: true }
}
});
// Output:
// {
// "type": "checklist",
// "data": {
// "items": [
// { "text": "Buy groceries", "checked": true },
// { "text": "Clean house", "checked": false }
// ]
// }
// }
```
--------------------------------
### Install editorjs-paragraph-with-alignment
Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md
Install the community plugin for paragraph blocks with alignment support using npm.
```bash
npm i editorjs-paragraph-with-alignment
```
--------------------------------
### Editor.js Selection Guide
Source: https://github.com/schema31/editor-js-ai-skill/blob/main/README.md
A reference guide for selecting the appropriate Editor.js configuration or tool implementation based on development needs.
```text
Working with Editor.js and need...
Basic setup and config → Installation & Configuration
Adding content blocks → Official Block Tools (Header, List, Table, Image, etc.)
Text formatting → Inline Tools (Bold, Marker, Underline, etc.)
Block-level options → Block Tunes (alignment, delete, move)
Building your own block → Tools API — Custom Block Tool
Building your own inline format → Tools API — Custom Inline Tool
Read-only display → Read-Only Mode
Multi-language support → i18n
Rendering JSON as HTML → Server-Side Rendering (JS, PHP, Python)
Framework integration → React, Vue 3, Vanilla JS examples
TypeScript types → TypeScript Support
```
--------------------------------
### Initialize Editor.js (Full Configuration)
Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md
Configure a comprehensive Editor.js instance with various tools, inline toolbars, tunes, and event handlers. This setup allows for advanced customization and functionality.
```javascript
import EditorJS from '@editorjs/editorjs';
import Header from '@editorjs/header';
import List from '@editorjs/list';
import Checklist from '@editorjs/checklist';
import Quote from '@editorjs/quote';
import Warning from '@editorjs/warning';
import Code from '@editorjs/code';
import Delimiter from '@editorjs/delimiter';
import Table from '@editorjs/table';
import ImageTool from '@editorjs/image';
import Embed from '@editorjs/embed';
import Marker from '@editorjs/marker';
import Underline from '@editorjs/underline';
import InlineCode from '@editorjs/inline-code';
const editor = new EditorJS({
holder: 'editorjs',
placeholder: 'Start writing your story...',
autofocus: true,
logLevel: 'ERROR',
defaultBlock: 'paragraph',
inlineToolbar: ['link', 'marker', 'bold', 'italic'],
tunes: ['alignmentTune'],
tools: {
header: {
class: Header,
inlineToolbar: true,
config: {
placeholder: 'Enter a heading',
levels: [1, 2, 3, 4],
defaultLevel: 2
},
shortcut: 'CMD+SHIFT+H'
},
list: {
class: List,
inlineToolbar: true,
config: { defaultStyle: 'unordered' }
},
checklist: { class: Checklist, inlineToolbar: true },
quote: {
class: Quote,
inlineToolbar: true,
config: {
quotePlaceholder: 'Enter a quote',
captionPlaceholder: 'Quote author'
}
},
warning: {
class: Warning,
inlineToolbar: true,
config: {
titlePlaceholder: 'Title',
messagePlaceholder: 'Message'
}
},
code: { class: Code },
delimiter: Delimiter,
table: {
class: Table,
inlineToolbar: true,
config: { rows: 2, cols: 3 }
},
image: {
class: ImageTool,
config: {
endpoints: {
byFile: '/api/upload/image',
byUrl: '/api/fetch/url'
}
}
},
embed: {
class: Embed,
config: {
services: { youtube: true, vimeo: true, codepen: true, github: true }
}
},
marker: { class: Marker, shortcut: 'CMD+SHIFT+M' },
underline: { class: Underline, shortcut: 'CMD+U' },
inlineCode: { class: InlineCode, shortcut: 'CMD+SHIFT+C' }
},
data: {},
onReady: () => {
console.log('Editor.js is ready!');
},
onChange: (api, event) => {
console.log('Content changed:', event);
},
readOnly: false,
i18n: { messages: {} }
});
```
--------------------------------
### Claude Code Plugin Installation
Source: https://github.com/schema31/editor-js-ai-skill/blob/main/README.md
Commands to register and install the Editor.js skill within the Claude Code environment.
```bash
/plugin marketplace add Schema31/Editor-js-ai-skill
```
```bash
/plugin install editorjs-skills@editorjs-skills
```
--------------------------------
### Initialize Editor.js (Minimal)
Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md
Create a basic Editor.js instance by specifying the holder element ID. This setup is suitable for simple use cases.
```javascript
const editor = new EditorJS({
holder: 'editorjs'
});
```
--------------------------------
### Configuring Editor.js Plugins
Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md
Examples of how to configure various community plugins such as alignment, color, and annotation tools.
```APIDOC
## Plugin Configuration
### Alignment Tune
- **Config**: `default` (string), `blocks` (object mapping block types to alignment).
### Text Color Plugin
- **Config**:
- `colorCollections` (array): List of available colors.
- `defaultColor` (string): Default color hex code.
- `type` (string): 'text' or 'marker'.
- `customPicker` (boolean): Enable custom color selection.
### Hyperlink Plugin
- **Config**:
- `shortcut` (string): Trigger key combination.
- `target` (string): Link target attribute.
- `rel` (string): Link relationship attribute.
- `availableTargets` (array): Allowed target values.
- `availableRels` (array): Allowed rel values.
```
--------------------------------
### Custom Tool: Inline Tool Example
Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md
Provides a comprehensive example of creating a custom inline tool in Editor.js, including its rendering, state management, and surrounding/unwrapping logic.
```APIDOC
## Tools API — Creating a Custom Inline Tool
This section details the creation of a custom inline tool. It covers defining the tool's properties, its rendering logic, how it interacts with the editor's selection, and its state management.
### Inline Tool Properties
- `isInline`: Must return `true` for inline tools.
- `sanitize`: Defines allowed HTML attributes for the tool's tag.
- `tag`: The HTML tag to be used for the inline tool (e.g., 'SPAN').
- `class`: CSS class applied to the tool's element.
- `shortcut`: Keyboard shortcut for activating the tool.
### Inline Tool Methods
- `render()`: Renders the tool's button for the inline toolbar.
- `surround(range)`: Wraps the selected content with the tool's tag or unwraps it if already applied.
- `wrap(range)`: Creates the HTML element and inserts it around the selected content.
- `unwrap(range)`: Removes the tool's HTML element and restores the original content.
- `checkState()`: Updates the tool's `state` based on the current selection.
### State Management
- `state` (getter/setter): Manages the active state of the inline tool, toggling the active class on its button.
```javascript
class MyInlineTool {
static get isInline() { return true; }
static get sanitize() {
return { span: { class: 'my-custom-style' } };
}
get state() { return this._state; }
set state(state) {
this._state = state;
this.button.classList.toggle(this.api.styles.inlineToolButtonActive, state);
}
constructor({ api }) {
this.api = api;
this._state = false;
this.tag = 'SPAN';
this.class = 'my-custom-style';
}
render() {
this.button = document.createElement('button');
this.button.type = 'button';
this.button.innerHTML = '';
this.button.classList.add(this.api.styles.inlineToolButton);
return this.button;
}
surround(range) {
if (this.state) { this.unwrap(range); }
else { this.wrap(range); }
}
wrap(range) {
const selectedText = range.extractContents();
const span = document.createElement(this.tag);
span.classList.add(this.class);
span.appendChild(selectedText);
range.insertNode(span);
this.api.selection.expandToTag(span);
}
unwrap(range) {
const span = this.api.selection.findParentTag(this.tag, this.class);
const text = range.extractContents();
span.remove();
range.insertNode(text);
}
checkState() {
const span = this.api.selection.findParentTag(this.tag, this.class);
this.state = !!span;
}
static get shortcut() { return 'CMD+SHIFT+S'; }
}
```
```
--------------------------------
### Repository Structure
Source: https://github.com/schema31/editor-js-ai-skill/blob/main/README.md
The directory layout of the Editor.js AI skill repository, highlighting configuration and example files.
```text
├── README.md
├── context7.json # Context7 configuration
├── .claude-plugin/
│ └── marketplace.json # Claude Code plugin registration
└── skills/
└── editorjs/
├── SKILL.md # Main skill documentation
└── examples/
├── basic-setup.js # Minimal and full configuration
├── custom-block-tool.js # Complete custom block tool example
├── custom-inline-tool.js # Complete custom inline tool example
└── server-rendering.js # JSON-to-HTML rendering (Node.js)
```
--------------------------------
### Configure Full Editor.js Instance
Source: https://context7.com/schema31/editor-js-ai-skill/llms.txt
Set up a comprehensive editor instance with custom tools, configuration options, pre-loaded data, and event callbacks.
```javascript
import EditorJS from '@editorjs/editorjs';
import Header from '@editorjs/header';
import List from '@editorjs/list';
import Checklist from '@editorjs/checklist';
import Quote from '@editorjs/quote';
import Warning from '@editorjs/warning';
import Code from '@editorjs/code';
import Delimiter from '@editorjs/delimiter';
import Table from '@editorjs/table';
import ImageTool from '@editorjs/image';
import Embed from '@editorjs/embed';
import Marker from '@editorjs/marker';
import Underline from '@editorjs/underline';
import InlineCode from '@editorjs/inline-code';
const editor = new EditorJS({
holder: 'editorjs',
placeholder: 'Start writing your article...',
autofocus: true,
logLevel: 'ERROR',
defaultBlock: 'paragraph',
inlineToolbar: ['link', 'marker', 'bold', 'italic', 'underline', 'inlineCode'],
tools: {
header: {
class: Header,
inlineToolbar: true,
config: {
placeholder: 'Enter a heading',
levels: [1, 2, 3, 4],
defaultLevel: 2
},
shortcut: 'CMD+SHIFT+H'
},
list: {
class: List,
inlineToolbar: true,
config: { defaultStyle: 'unordered' }
},
checklist: { class: Checklist, inlineToolbar: true },
quote: {
class: Quote,
inlineToolbar: true,
config: {
quotePlaceholder: 'Enter a quote',
captionPlaceholder: 'Quote author'
}
},
warning: {
class: Warning,
inlineToolbar: true,
config: {
titlePlaceholder: 'Title',
messagePlaceholder: 'Message'
}
},
code: { class: Code },
delimiter: Delimiter,
table: {
class: Table,
inlineToolbar: true,
config: { rows: 2, cols: 3, withHeadings: true }
},
image: {
class: ImageTool,
config: {
endpoints: {
byFile: '/api/upload/image',
byUrl: '/api/fetch/url'
}
}
},
embed: {
class: Embed,
config: {
services: { youtube: true, vimeo: true, codepen: true }
}
},
marker: { class: Marker, shortcut: 'CMD+SHIFT+M' },
underline: { class: Underline, shortcut: 'CMD+U' },
inlineCode: { class: InlineCode, shortcut: 'CMD+SHIFT+C' }
},
data: {
time: Date.now(),
blocks: [
{ type: 'header', data: { text: 'Welcome to Editor.js', level: 2 } },
{ type: 'paragraph', data: { text: 'This is pre-loaded content.' } }
]
},
onReady: () => {
console.log('Editor.js is ready!');
},
onChange: (api, event) => {
console.log('Content changed:', event.type);
}
});
```
--------------------------------
### Configure Warning Tool
Source: https://context7.com/schema31/editor-js-ai-skill/llms.txt
Configure the Warning tool with custom placeholders for title and message.
```javascript
import Warning from '@editorjs/warning';
const editor = new EditorJS({
tools: {
warning: {
class: Warning,
inlineToolbar: true,
config: {
titlePlaceholder: 'Title',
messagePlaceholder: 'Message'
}
}
}
});
// Output: { "type": "warning", "data": { "title": "Caution", "message": "Irreversible action." } }
```
--------------------------------
### Configure Block Tunes
Source: https://context7.com/schema31/editor-js-ai-skill/llms.txt
Initialize Editor.js with alignment tunes applied to specific tools or globally.
```javascript
import AlignmentTune from 'editorjs-text-alignment-blocktune';
import Header from '@editorjs/header';
import Paragraph from '@editorjs/paragraph';
const editor = new EditorJS({
tools: {
alignmentTune: {
class: AlignmentTune,
config: {
default: 'left',
blocks: { header: 'center', list: 'left' }
}
},
// Apply tune to specific tools
header: { class: Header, tunes: ['alignmentTune'] },
paragraph: { class: Paragraph, tunes: ['alignmentTune'] }
},
// OR apply to ALL blocks globally:
tunes: ['alignmentTune']
});
```
--------------------------------
### Check Editor Ready State with Promise
Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md
Use the `isReady` property with a Promise to execute code once the editor is fully initialized. Handles potential initialization failures.
```javascript
// Promise
editor.isReady
.then(() => console.log('Ready!'))
.catch((reason) => console.log(`Failed: ${reason}`));
```
--------------------------------
### Configure Read-Only Mode
Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md
Enable read-only mode during initialization or toggle it at runtime. Tools must support read-only mode via a static getter.
```javascript
// Initialize in read-only
const editor = new EditorJS({
readOnly: true,
tools: { /* ... */ },
data: savedData
});
// Toggle at runtime
await editor.readOnly.toggle();
// Check state
const isReadOnly = editor.readOnly.isEnabled;
```
--------------------------------
### Check Editor Ready State with async/await
Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md
Use `async/await` with the `isReady` property for a more synchronous-looking way to wait for editor initialization. Ensure the surrounding function is `async`.
```javascript
// async/await
await editor.isReady;
```
--------------------------------
### Apply Custom Tunes Per Tool
Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md
Specify which custom tunes should be available for individual tools by listing them in the tool's 'tunes' property.
```javascript
tools: {
header: { class: Header, tunes: ['alignmentTune'] },
paragraph: { class: Paragraph, tunes: ['alignmentTune'] }
}
```
--------------------------------
### Create a Custom Inline Tool
Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md
Implement the Inline Tool interface to handle text selection formatting. Ensure the class includes render, surround, and state management methods.
```javascript
class MyInlineTool {
static get isInline() { return true; }
static get sanitize() {
return { span: { class: 'my-custom-style' } };
}
get state() { return this._state; }
set state(state) {
this._state = state;
this.button.classList.toggle(this.api.styles.inlineToolButtonActive, state);
}
constructor({ api }) {
this.api = api;
this._state = false;
this.tag = 'SPAN';
this.class = 'my-custom-style';
}
render() {
this.button = document.createElement('button');
this.button.type = 'button';
this.button.innerHTML = '';
this.button.classList.add(this.api.styles.inlineToolButton);
return this.button;
}
surround(range) {
if (this.state) { this.unwrap(range); }
else { this.wrap(range); }
}
wrap(range) {
const selectedText = range.extractContents();
const span = document.createElement(this.tag);
span.classList.add(this.class);
span.appendChild(selectedText);
range.insertNode(span);
this.api.selection.expandToTag(span);
}
unwrap(range) {
const span = this.api.selection.findParentTag(this.tag, this.class);
const text = range.extractContents();
span.remove();
range.insertNode(text);
}
checkState() {
const span = this.api.selection.findParentTag(this.tag, this.class);
this.state = !!span;
}
static get shortcut() { return 'CMD+SHIFT+S'; }
}
```
--------------------------------
### Configure Inline Tools
Source: https://context7.com/schema31/editor-js-ai-skill/llms.txt
Register inline tools and define their keyboard shortcuts and toolbar visibility.
```javascript
import Marker from '@editorjs/marker';
import Underline from '@editorjs/underline';
import InlineCode from '@editorjs/inline-code';
const editor = new EditorJS({
tools: {
marker: { class: Marker, shortcut: 'CMD+SHIFT+M' },
underline: { class: Underline, shortcut: 'CMD+U' },
inlineCode: { class: InlineCode, shortcut: 'CMD+SHIFT+C' }
},
inlineToolbar: ['bold', 'italic', 'link', 'marker', 'underline', 'inlineCode']
});
// Marker wraps text in: highlighted text
// Underline wraps text in: underlined text
// Inline Code wraps text in: code
```
--------------------------------
### Configure Checklist Tool
Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md
Configure the Checklist tool with inline toolbar support. Requires `@editorjs/checklist` package.
```bash
npm i @editorjs/checklist
```
```javascript
checklist: { class: Checklist, inlineToolbar: true }
```
--------------------------------
### Configure Annotation Plugin
Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md
Configure the Annotation plugin with a placeholder text and an option to include links.
```javascript
annotation: {
class: Annotation,
config: { placeholder: 'Add a note', withLink: true }
}
```
--------------------------------
### Configure Embed Tool
Source: https://context7.com/schema31/editor-js-ai-skill/llms.txt
Configure the Embed tool to support various services, including custom service definitions.
```javascript
import Embed from '@editorjs/embed';
const editor = new EditorJS({
tools: {
embed: {
class: Embed,
config: {
services: {
youtube: true,
vimeo: true,
codepen: true,
github: true,
twitter: true,
// Custom service
myService: {
regex: /https?:\/\/mysite\.com\/embed\/(.+)/,
embedUrl: 'https://mysite.com/embed/<%= remote_id %>',
html: '',
height: 300,
width: 600
}
}
}
}
}
});
// Output:
// {
// "type": "embed",
// "data": {
// "service": "youtube",
// "source": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
// "embed": "https://www.youtube.com/embed/dQw4w9WgXcQ",
// "width": 580, "height": 320, "caption": ""
// }
// }
```
--------------------------------
### Configure Image Tool
Source: https://context7.com/schema31/editor-js-ai-skill/llms.txt
Configure the Image tool with endpoints or a custom uploader for handling image files and URLs.
```javascript
import ImageTool from '@editorjs/image';
const editor = new EditorJS({
tools: {
image: {
class: ImageTool,
config: {
endpoints: {
byFile: '/api/upload/image',
byUrl: '/api/fetch/url'
},
// OR custom uploader:
uploader: {
uploadByFile(file) {
const formData = new FormData();
formData.append('image', file);
return fetch('/api/upload', { method: 'POST', body: formData })
.then(res => res.json())
.then(data => ({ success: 1, file: { url: data.url } }));
},
uploadByUrl(url) {
return fetch('/api/fetch-url', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ url })
})
.then(res => res.json())
.then(data => ({ success: 1, file: { url: data.url } }));
}
}
}
}
}
});
// Output:
// {
// "type": "image",
// "data": {
// "file": { "url": "https://example.com/image.jpg" },
// "caption": "Image caption",
// "withBorder": false, "stretched": false, "withBackground": false
// }
// }
```
--------------------------------
### Editor.js Configuration with TypeScript
Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md
Basic Editor.js configuration using TypeScript, including defining tools and their properties. Requires importing necessary types from '@editorjs/editorjs'.
```typescript
import EditorJS, {
EditorConfig, OutputData, BlockToolConstructable,
InlineToolConstructable, API, BlockAPI, ToolConfig, LogLevels
} from '@editorjs/editorjs';
const config: EditorConfig = {
holder: 'editorjs',
tools: {
header: {
class: Header as unknown as BlockToolConstructable,
config: { levels: [1, 2, 3], defaultLevel: 2 }
}
}
};
const editor = new EditorJS(config);
editor.save().then((data: OutputData) => {
data.blocks.forEach(block => console.log(block.type, block.data));
});
```
--------------------------------
### Configure Hyperlink Plugin
Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md
Configure the Hyperlink plugin with a keyboard shortcut, target attribute, rel attribute, and lists of available targets and rels.
```javascript
hyperlink: {
class: Hyperlink,
config: {
shortcut: 'CMD+L', target: '_blank', rel: 'nofollow',
availableTargets: ['_blank', '_self'],
availableRels: ['nofollow', 'noreferrer']
}
}
```
--------------------------------
### Configure List Tool
Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md
Configure the List tool with inline toolbar and a default style (ordered or unordered). Requires `@editorjs/list` package.
```bash
npm i @editorjs/list
```
```javascript
list: {
class: List,
inlineToolbar: true,
config: { defaultStyle: 'unordered' }
}
```
--------------------------------
### Define Multiple Toolbox Entries
Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md
Return an array of objects in the static toolbox getter to provide multiple tool variations.
```javascript
class HeadingTool {
static get toolbox() {
return [
{ icon: '', title: 'Heading 1', data: { level: 1 } },
{ icon: '', title: 'Heading 2', data: { level: 2 } },
{ icon: '', title: 'Heading 3', data: { level: 3 } }
];
}
}
```
--------------------------------
### Block Tunes Configuration
Source: https://context7.com/schema31/editor-js-ai-skill/llms.txt
Configure block-level settings like text alignment within the Editor.js instance.
```APIDOC
## Block Tunes Configuration
### Description
Configure block-level settings like text alignment that appear in the block's settings menu.
### Implementation
```javascript
import AlignmentTune from 'editorjs-text-alignment-blocktune';
const editor = new EditorJS({
tools: {
alignmentTune: {
class: AlignmentTune,
config: { default: 'left', blocks: { header: 'center', list: 'left' } }
},
header: { class: Header, tunes: ['alignmentTune'] }
},
tunes: ['alignmentTune']
});
```
```
--------------------------------
### Configure Code and Delimiter Tools
Source: https://context7.com/schema31/editor-js-ai-skill/llms.txt
Register the Code and Delimiter tools in the EditorJS configuration.
```javascript
import Code from '@editorjs/code';
import Delimiter from '@editorjs/delimiter';
const editor = new EditorJS({
tools: {
code: { class: Code },
delimiter: Delimiter
}
});
// Code output: { "type": "code", "data": { "code": "const x = 42;" } }
// Delimiter output: { "type": "delimiter", "data": {} }
```
--------------------------------
### Minimal Block Tool Implementation
Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md
A basic structure for a custom Editor.js block tool, including constructor, static toolbox getter, render method, save method, and validation.
```javascript
class MyTool {
constructor({ data, api, config, readOnly, block }) {
this.data = data || {};
this.api = api;
this.config = config;
this.readOnly = readOnly;
}
static get toolbox() {
return { icon: '', title: 'My Tool' };
}
render() {
this.wrapper = document.createElement('div');
this.wrapper.classList.add('my-tool');
this.wrapper.contentEditable = !this.readOnly;
this.wrapper.innerHTML = this.data.text || '';
return this.wrapper;
}
save(blockContent) {
return { text: blockContent.innerHTML };
}
validate(savedData) {
return savedData.text.trim() !== '';
}
static get isReadOnlySupported() {
return true;
}
}
```
--------------------------------
### Configure Text Color Plugin
Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md
Configure the ColorPlugin to define available colors, default color, type (text or marker), and enable a custom color picker.
```javascript
color: {
class: ColorPlugin,
config: {
colorCollections: ['#000000', '#D0021B', '#F5A623', '#4A90E2', '#7ED321'],
defaultColor: '#000000',
type: 'text', // 'text' for text color, 'marker' for background
customPicker: true
}
}
```
--------------------------------
### Optional Block Tool Methods and Static Getters
Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md
Demonstrates optional methods and static getters for enhancing custom Editor.js block tools, including rendering settings, merging, sanitization, conversion, shortcuts, and paste handling.
```javascript
class MyTool {
renderSettings() {
return [
{
icon: '',
label: 'With border',
toggle: 'withBorder',
isActive: this.data.withBorder,
onActivate: () => {
this.data.withBorder = !this.data.withBorder;
this.wrapper.classList.toggle('with-border');
}
}
];
}
merge(data) {
this.data.text += data.text;
this.wrapper.innerHTML = this.data.text;
}
destroy() {
// Remove event listeners, clear cache
}
static get sanitize() {
return {
text: { b: true, i: true, a: { href: true, target: '_blank' } }
};
}
static get conversionConfig() {
return { export: 'text', import: 'text' };
}
// Function-based conversion (for complex data)
static get conversionConfig() {
return {
export: (data) => data.items.join('. '),
import: (string) => ({
items: string.split('.').map(s => s.trim()).filter(Boolean),
style: 'unordered'
})
};
}
static get shortcut() { return 'CMD+SHIFT+M'; }
static get enableLineBreaks() { return false; }
static get pasteConfig() {
return {
tags: ['IMG'],
files: { mimeTypes: ['image/*'], extensions: ['gif', 'jpg', 'png', 'webp'] },
patterns: { image: /https?:
//S+\.(gif|jpe?g|tiff|png|webp)$/i }
};
}
onPaste(event) {
switch (event.type) {
case 'tag': {
const element = event.detail.data;
this.data = { url: element.src };
break;
}
case 'pattern': {
this.data = { url: event.detail.data };
break;
}
case 'file': {
const reader = new FileReader();
reader.onload = (e) => { this.data = { url: e.target.result }; };
reader.readAsDataURL(event.detail.file);
break;
}
}
}
}
```
--------------------------------
### Configure Header Tool
Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md
Configure the Header tool with options for inline toolbar, placeholder text, heading levels, and default level. Requires `@editorjs/header` package.
```bash
npm i @editorjs/header
```
```javascript
header: {
class: Header,
inlineToolbar: true,
config: {
placeholder: 'Enter a heading',
levels: [1, 2, 3, 4, 5, 6],
defaultLevel: 2
}
}
```
--------------------------------
### Apply Custom Tunes Globally
Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md
Configure Editor.js to apply custom tunes to all blocks by specifying them in the main 'tunes' array.
```javascript
import AlignmentTune from 'editorjs-text-alignment-blocktune';
const editor = new EditorJS({
tools: {
alignmentTune: {
class: AlignmentTune,
config: { default: 'left', blocks: { header: 'center', list: 'left' } }
}
},
tunes: ['alignmentTune'] // Apply to ALL blocks
});
```
--------------------------------
### Register Custom AlertBox Tool with EditorJS
Source: https://context7.com/schema31/editor-js-ai-skill/llms.txt
Initialize the Editor.js instance and register the custom 'AlertBox' block tool. This configuration sets up the editor holder, defines the tools available, and configures the custom tool with inline toolbar support and default settings.
```javascript
// Register the custom tool
const editor = new EditorJS({
holder: 'editorjs',
tools: {
alertBox: {
class: AlertBox,
inlineToolbar: true,
config: {
defaultType: 'info',
placeholder: 'Type your alert message...'
}
}
}
});
```
--------------------------------
### Configure Alignment Tune Tool
Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md
Configure the AlignmentTuneTool with default alignment and specific block type alignments.
```javascript
alignmentTune: {
class: AlignmentTuneTool,
config: { default: 'left', blocks: { header: 'center' } }
}
```
--------------------------------
### Configure Internationalization (i18n)
Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md
Provide custom translations for UI elements, tool names, and specific tool configurations via the i18n property.
```javascript
const editor = new EditorJS({
i18n: {
messages: {
ui: {
"blockTunes": {
"toggler": { "Click to tune": "Click to tune", "or drag to move": "or drag to move" }
},
"inlineToolbar": { "converter": { "Convert to": "Convert to" } },
"toolbar": { "toolbox": { "Add": "Add" } },
"popover": { "Filter": "Filter", "Nothing found": "Nothing found" }
},
toolNames: {
"Text": "Text", "Heading": "Heading", "List": "List",
"Checklist": "Checklist", "Quote": "Quote", "Warning": "Warning",
"Code": "Code", "Delimiter": "Delimiter", "Table": "Table",
"Image": "Image", "Marker": "Marker", "Bold": "Bold",
"Italic": "Italic", "Link": "Link", "Underline": "Underline",
"InlineCode": "Inline Code"
},
tools: {
"header": { "Heading 1": "Heading 1", "Heading 2": "Heading 2" },
"list": { "Ordered": "Ordered", "Unordered": "Unordered" },
"table": {
"Add column to left": "Add column to left",
"Add column to right": "Add column to right",
"Delete column": "Delete column",
"Add row above": "Add row above",
"Add row below": "Add row below",
"Delete row": "Delete row",
"With headings": "With headings",
"Without headings": "Without headings"
}
},
blockTunes: {
"delete": { "Delete": "Delete", "Click to delete": "Click to delete" },
"moveUp": { "Move up": "Move up" },
"moveDown": { "Move down": "Move down" }
}
}
}
});
```
--------------------------------
### Manage Read-Only Mode
Source: https://context7.com/schema31/editor-js-ai-skill/llms.txt
Initialize the editor in read-only mode and toggle it at runtime.
```javascript
import EditorJS from '@editorjs/editorjs';
import Header from '@editorjs/header';
import List from '@editorjs/list';
// Initialize in read-only mode
const editor = new EditorJS({
holder: 'editorjs-readonly',
readOnly: true,
tools: {
header: { class: Header },
list: { class: List }
},
data: {
blocks: [
{ type: 'header', data: { text: 'Read-only article', level: 1 } },
{ type: 'paragraph', data: { text: 'This content cannot be edited.' } }
]
}
});
// Toggle read-only at runtime
async function toggleReadOnly() {
await editor.readOnly.toggle();
console.log('Read-only:', editor.readOnly.isEnabled);
}
// Check current state
const isReadOnly = editor.readOnly.isEnabled;
```
--------------------------------
### Configure Paragraph Tool
Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md
Configure the Paragraph tool with inline toolbar support and options to preserve blank lines. Requires `@editorjs/paragraph` package.
```bash
npm i @editorjs/paragraph
```
```javascript
paragraph: {
class: Paragraph,
inlineToolbar: true,
config: { placeholder: 'Start typing...', preserveBlank: true }
}
```
--------------------------------
### Integrate Editor.js with React
Source: https://github.com/schema31/editor-js-ai-skill/blob/main/skills/editorjs/SKILL.md
Uses useRef to manage the editor instance and useEffect to handle initialization and cleanup.
```jsx
import { useEffect, useRef } from 'react';
import EditorJS from '@editorjs/editorjs';
import Header from '@editorjs/header';
import List from '@editorjs/list';
function EditorComponent({ data, onChange }) {
const editorRef = useRef(null);
const instanceRef = useRef(null);
useEffect(() => {
if (!instanceRef.current) {
instanceRef.current = new EditorJS({
holder: editorRef.current,
tools: { header: Header, list: List },
data: data || {},
onChange: async (api) => {
const savedData = await api.saver.save();
onChange?.(savedData);
}
});
}
return () => {
instanceRef.current?.destroy();
instanceRef.current = null;
};
}, []);
return