Code Block
The CodeBlock node provides a block-level code container (<pre><code>). It preserves whitespace, disallows marks (no bold, italic, etc. inside code), and supports an optional language attribute rendered as a CSS class on the inner <code> element. A triple-backtick input rule and a keyboard shortcut (Mod-Alt-C) are included.
Live Playground
Section titled “Live Playground”Type three backticks (```) followed by an optional language name and press space to create a code block. Use Mod-Alt-C to toggle.
Vanilla JS preview - Angular components produce the same output
Vanilla JS preview - React components produce the same output
The buttons above the editor are custom HTML buttons wired to toggleCodeBlock(). Active state is tracked with editor.isActive('codeBlock').
CodeBlock is included in StarterKit. If you are building a custom setup without StarterKit, add it manually:
import { Editor, Document, Text, Paragraph, CodeBlock } from '@domternal/core';
const editor = new Editor({ element: document.getElementById('editor')!, extensions: [Document, Text, Paragraph, CodeBlock], content: '<pre><code>const x = 42;</code></pre>',});import { Component, signal } from '@angular/core';import { DomternalEditorComponent } from '@domternal/angular';import { Editor, Document, Text, Paragraph, CodeBlock } from '@domternal/core';
@Component({ selector: 'app-editor', imports: [DomternalEditorComponent], template: ` <domternal-editor [extensions]="extensions" [content]="content" (editorCreated)="editor.set($event)" /> `,})export class EditorComponent { editor = signal<Editor | null>(null); extensions = [Document, Text, Paragraph, CodeBlock]; content = '<pre><code>const x = 42;</code></pre>';}import { Domternal } from '@domternal/react';import { Document, Text, Paragraph, CodeBlock } from '@domternal/core';
export default function Editor() { return ( <Domternal extensions={[Document, Text, Paragraph, CodeBlock]} content="<pre><code>const x = 42;</code></pre>" > <Domternal.Content /> </Domternal> );}Schema
Section titled “Schema”| Property | Value |
|---|---|
| ProseMirror name | codeBlock |
| Type | Node |
| Group | block |
| Content | text* (zero or more text nodes) |
| Marks | None (marks are not allowed inside code blocks) |
| Code | Yes (treated as code content) |
| Defining | Yes |
| HTML tag | <pre> wrapping a <code> element |
The code: true property tells ProseMirror that this node contains code, which affects how Enter, Tab, and other keys behave inside it. The marks: '' property prevents any marks (bold, italic, links, etc.) from being applied to text inside a code block.
Options
Section titled “Options”| Option | Type | Default | Description |
|---|---|---|---|
languageClassPrefix | string | 'language-' | CSS class prefix for the language attribute on the <code> element |
exitOnTripleEnter | boolean | true | Whether pressing Enter three times (two empty lines) exits the code block |
HTMLAttributes | Record<string, unknown> | {} | HTML attributes added to the <pre> element |
Custom language class prefix
Section titled “Custom language class prefix”import { CodeBlock } from '@domternal/core';
// Use 'lang-' instead of 'language-'const CustomCodeBlock = CodeBlock.configure({ languageClassPrefix: 'lang-',});With this configuration, a code block with language: 'typescript' renders as <pre><code class="lang-typescript">.
Disable triple-enter exit
Section titled “Disable triple-enter exit”import { CodeBlock } from '@domternal/core';
const CustomCodeBlock = CodeBlock.configure({ exitOnTripleEnter: false,});Custom HTML attributes
Section titled “Custom HTML attributes”import { CodeBlock } from '@domternal/core';
const CustomCodeBlock = CodeBlock.configure({ HTMLAttributes: { class: 'my-code-block' },});Attributes
Section titled “Attributes”| Attribute | Type | Default | Description |
|---|---|---|---|
language | string | null | null | The programming language for syntax highlighting |
The language attribute is parsed from the <code> element’s CSS class (e.g., class="language-typescript" becomes language: 'typescript'). It is rendered as a class on the inner <code> element, not as an HTML attribute on <pre>.
Commands
Section titled “Commands”| Command | Description |
|---|---|
setCodeBlock({ language? }) | Convert the current block to a code block |
toggleCodeBlock({ language? }) | Toggle between code block and paragraph |
// Convert the current block to a code blockeditor.commands.setCodeBlock();
// Set a code block with a languageeditor.commands.setCodeBlock({ language: 'typescript' });
// Toggle between code block and paragrapheditor.commands.toggleCodeBlock();
// With chainingeditor.chain().focus().toggleCodeBlock({ language: 'css' }).run();toggleCodeBlock converts a code block back to a paragraph if the current block is already a code block.
Keyboard shortcuts
Section titled “Keyboard shortcuts”| Shortcut | Command |
|---|---|
Mod-Alt-C | toggleCodeBlock() |
Enter | Exit code block when last two lines are empty (triple-enter) |
ArrowDown | Exit code block when cursor is at the end and it is the last block |
The triple-enter behavior works like this: when typing inside a code block, pressing Enter creates new lines as expected. But if the last two characters are both newlines (two empty lines at the end), the next Enter press removes those empty lines and creates a new paragraph below the code block. This can be disabled with exitOnTripleEnter: false.
The ArrowDown behavior creates a new paragraph below when the cursor is at the very end of a code block and there is no node after it. This prevents the cursor from getting “trapped” in a code block at the end of the document.
Input rules
Section titled “Input rules”| Input | Result |
|---|---|
``` + space | Code block (no language) |
```js + space | Code block with language js |
```typescript + space | Code block with language typescript |
Type three backticks at the start of a new line, optionally followed by a language identifier, then press space. The line converts to a code block with the specified language.
The regex pattern is /^```([a-z]*)?[\s\n]$/, which accepts lowercase letters for the language name.
Toolbar items
Section titled “Toolbar items”CodeBlock registers a button in the toolbar with the name codeBlock in group blocks at priority 140.
| Item | Command | Icon | Shortcut |
|---|---|---|---|
| Code Block | toggleCodeBlock | codeBlock | Mod-Alt-C |
JSON representation
Section titled “JSON representation”{ "type": "codeBlock", "attrs": { "language": "typescript" }, "content": [ { "type": "text", "text": "const x: number = 42;\nconsole.log(x);" } ]}A code block without a language:
{ "type": "codeBlock", "attrs": { "language": null }, "content": [ { "type": "text", "text": "plain text code" } ]}An empty code block:
{ "type": "codeBlock", "attrs": { "language": null }}Source
Section titled “Source”@domternal/core - CodeBlock.ts