Custom Code Block Theme & Language
To configure a code block highlighting theme and language, you can extend the editor's default schema with a new codeBlock, which you can pass options into when creating. You can then use a shiki highlighter to add custom syntax highlighting.
First use the shiki-codegen CLI to create a shiki.bundle.ts file. You can then pass this file into the codeBlock options when creating it.
Relevant Docs:
import { BlockNoteSchema, createCodeBlockSpec } from "@blocknote/core";import "@blocknote/core/fonts/inter.css";import { BlockNoteView } from "@blocknote/mantine";import "@blocknote/mantine/style.css";import { useCreateBlockNote } from "@blocknote/react";// Bundle created from `npx shiki-codegen --langs typescript,javascript,react --themes light-plus,dark-plus --engine javascript --precompiled ./shiki.bundle.ts`import { createHighlighter } from "./shiki.bundle";export default function App() { // Creates a new editor instance. const editor = useCreateBlockNote({ schema: BlockNoteSchema.create().extend({ blockSpecs: { codeBlock: createCodeBlockSpec({ indentLineWithTab: true, defaultLanguage: "typescript", supportedLanguages: { typescript: { name: "TypeScript", aliases: ["ts"], }, javascript: { name: "JavaScript", aliases: ["js"], }, vue: { name: "Vue", }, }, // This creates a highlighter, it can be asynchronous to load it afterwards createHighlighter: () => createHighlighter({ themes: ["dark-plus", "light-plus"], langs: [], }), }), }, }), initialContent: [ { type: "codeBlock", props: { language: "typescript", }, content: [ { type: "text", text: "const x = 3 * 4;", styles: {}, }, ], }, { type: "paragraph", }, { type: "heading", props: { textColor: "default", backgroundColor: "default", textAlignment: "left", level: 3, }, content: [ { type: "text", text: 'Click on "Typescript" above to see the different supported languages', styles: {}, }, ], }, { type: "paragraph", }, ], }); // Renders the editor instance using a React component. return <BlockNoteView editor={editor} />;}/* Generate by @shikijs/codegen */import type { DynamicImportLanguageRegistration, DynamicImportThemeRegistration, HighlighterGeneric,} from "@shikijs/types";import { createdBundledHighlighter } from "@shikijs/core";import { createJavaScriptRegexEngine } from "@shikijs/engine-javascript";type BundledLanguage = "typescript" | "ts" | "javascript" | "js" | "vue";type BundledTheme = "light-plus" | "dark-plus";type Highlighter = HighlighterGeneric<BundledLanguage, BundledTheme>;const bundledLanguages = { typescript: () => import("@shikijs/langs-precompiled/typescript"), ts: () => import("@shikijs/langs-precompiled/typescript"), javascript: () => import("@shikijs/langs-precompiled/javascript"), js: () => import("@shikijs/langs-precompiled/javascript"), vue: () => import("@shikijs/langs-precompiled/vue"),} as Record<BundledLanguage, DynamicImportLanguageRegistration>;const bundledThemes = { "light-plus": () => import("@shikijs/themes/light-plus"), "dark-plus": () => import("@shikijs/themes/dark-plus"),} as Record<BundledTheme, DynamicImportThemeRegistration>;const createHighlighter = /* @__PURE__ */ createdBundledHighlighter< BundledLanguage, BundledTheme>({ langs: bundledLanguages, themes: bundledThemes, engine: () => createJavaScriptRegexEngine(),});export { createHighlighter };export type { BundledLanguage, BundledTheme, Highlighter };