slash-editor
Components

Code Block Node View

Syntax-highlighted code blocks (lowlight) with a language selector, themed from your shadcn tokens.

Hover a code block to pick its language; Auto detects it from the code. Type /code, or ``` followed by a space, to add one.

Installation

bunx --bun shadcn@latest add @slash-editor/code-block-node-view

Usage

Highlighting is opt-in: createBlockKit keeps StarterKit's plain codeBlock unless you pass a highlighted node as the codeBlock option. It comes from its own entry, @slash-editor/core/code-block, so lowlight never lands in a bundle that doesn't use it. To get the language selector, pass the node extended with the view:

import { CodeBlock } from "@slash-editor/core/code-block";
import { ReactNodeViewRenderer } from "@tiptap/react";
import { CodeBlockNodeView } from "@/components/nodes/code-block-node-view";

const editor = useSlashEditor({
  blockKit: {
    codeBlock: CodeBlock.extend({ addNodeView: () => ReactNodeViewRenderer(CodeBlockNodeView) }),
  },
});

Without a view, codeBlock: codeBlock() alone highlights; style the hljs-* classes yourself or use the CSS this item installs.

Choosing languages

The default grammar set is lowlight's common (about 37 languages). Register your own lowlight instance for more or fewer languages — the selector lists whatever the instance has. The example imports both packages directly, so install them in your app first:

bun add lowlight highlight.js
import { codeBlock } from "@slash-editor/core/code-block";
import { createLowlight } from "lowlight";
import typescript from "highlight.js/lib/languages/typescript";

const lowlight = createLowlight({ typescript });

useSlashEditor({ blockKit: { codeBlock: codeBlock({ lowlight }) } });

With the view, extend first and configure after: CodeBlock.extend({ addNodeView }).configure({ lowlight }).

Behaviour

  • Same node. The block is still codeBlock with a language attribute, so block types, slash items, and markdown round-trips are unchanged.
  • Decorations only. Tokens are never stored in the document; undo and collaboration see plain text.
  • Themed. Token colours mix --chart-1…--chart-5 toward --foreground, so contrast holds in any theme; comments use --muted-foreground.
  • Aliases. A fence such as ```js keeps its js language and shows it in the selector.
  • Read-only. The selector is hidden when the editor is not editable.

On this page