### Install BlockNote AI Package Source: https://www.blocknotejs.org/docs/features/ai/getting-started Install the `@blocknote/xl-ai` package using npm. ```bash npm install @blocknote/xl-ai ``` -------------------------------- ### Install PDF Exporter Packages Source: https://www.blocknotejs.org/docs/features/export/pdf Install the necessary packages for PDF export functionality. ```bash npm install @blocknote/xl-pdf-exporter @react-pdf/renderer ``` -------------------------------- ### Install BlockNote Core with NPM Source: https://www.blocknotejs.org/docs/getting-started/vanilla-js Install only the vanilla JS parts of BlockNote using NPM. This is the first step for using BlockNote in a vanilla JavaScript project. ```bash npm install @blocknote/core ``` -------------------------------- ### Default Backend Setup with Vercel AI SDK (Next.js) Source: https://www.blocknotejs.org/docs/features/ai/backend-integration Use this setup for a default integration with BlockNote AI and an LLM via the Vercel AI SDK in a Next.js application. It handles tool definitions and document state injection. ```typescript import { openai } from "@ai-sdk/openai"; import { convertToModelMessages, streamText } from "ai"; import { aiDocumentFormats, injectDocumentStateMessages, toolDefinitionsToToolSet, } from "@blocknote/xl-ai/server"; // Allow streaming responses up to 30 seconds export const maxDuration = 30; export async function POST(req: Request) { const { messages, toolDefinitions } = await req.json(); const result = streamText({ model: openai("gpt-4.1"), // see https://ai-sdk.dev/docs/foundations/providers-and-models system: aiDocumentFormats.html.systemPrompt, messages: await convertToModelMessages( injectDocumentStateMessages(messages), ), tools: toolDefinitionsToToolSet(toolDefinitions), toolChoice: "required", }); return result.toUIMessageStreamResponse(); } ``` -------------------------------- ### Install BlockNote with Mantine Packages Source: https://www.blocknotejs.org/docs/getting-started/mantine Install the necessary BlockNote and Mantine packages using npm, pnpm, or bun. Ensure you have the core, React, and Mantine integrations for BlockNote, along with essential Mantine components. ```bash npm install @blocknote/core @blocknote/react @blocknote/mantine npm install @mantine/core @mantine/hooks @mantine/utils ``` ```bash pnpm add @blocknote/core @blocknote/react @blocknote/mantine npm install @mantine/core @mantine/hooks @mantine/utils ``` ```bash bun add @blocknote/core @blocknote/react @blocknote/mantine npm install @mantine/core @mantine/hooks @mantine/utils ``` -------------------------------- ### Install ODT Exporter Source: https://www.blocknotejs.org/docs/features/export/odt Install the required package to enable ODT export functionality. ```bash npm install @blocknote/xl-odt-exporter ``` -------------------------------- ### Install BlockNote ShadCN dependencies Source: https://www.blocknotejs.org/docs/getting-started/shadcn Commands to install the necessary BlockNote packages for ShadCN integration. ```console npm install @blocknote/core @blocknote/react @blocknote/shadcn ``` ```console pnpm add @blocknote/core @blocknote/react @blocknote/shadcn ``` ```console bun add @blocknote/core @blocknote/react @blocknote/shadcn ``` -------------------------------- ### Install DOCX Exporter Packages Source: https://www.blocknotejs.org/docs/features/export/docx Install the necessary packages for DOCX export. This includes the BlockNote exporter and the docx package. ```bash npm install @blocknote/xl-docx-exporter docx ``` -------------------------------- ### Install BlockNote Ariakit dependencies Source: https://www.blocknotejs.org/docs/getting-started/ariakit Use these commands to install the core, React, and Ariakit-specific packages for BlockNote. ```npm npm install @blocknote/core @blocknote/react @blocknote/ariakit ``` ```pnpm pnpm add @blocknote/core @blocknote/react @blocknote/ariakit ``` ```bun bun add @blocknote/core @blocknote/react @blocknote/ariakit ``` -------------------------------- ### Install Email Exporter Package Source: https://www.blocknotejs.org/docs/features/export/email Install the required dependency for email export functionality. ```bash npm install @blocknote/xl-email-exporter ``` -------------------------------- ### Set up Yjs Provider with PartyKit Source: https://www.blocknotejs.org/docs/features/collaboration Replace the default `WebrtcProvider` with `YPartyKitProvider` for development testing of collaborative features. Ensure you have installed the `y-partykit` package. ```typescript // npm install y-partykit import YPartyKitProvider from "y-partykit/provider"; const provider = new YPartyKitProvider( "blocknote-dev.yousefed.partykit.dev", // use a unique name as a "room" for your application: "your-project-name", doc, ); ``` -------------------------------- ### Create a BlockNote Editor Instance Source: https://www.blocknotejs.org/docs/getting-started/vanilla-js Create a new BlockNote editor instance and mount it to a specified HTML element. This is the basic setup for a vanilla JS BlockNote editor. ```typescript import { BlockNoteEditor } from "@blocknote/core"; const editor = BlockNoteEditor.create(); editor.mount(document.getElementById("root")); // element to append the editor to ``` -------------------------------- ### Creating a Custom Schema with Inline Content Source: https://www.blocknotejs.org/docs/features/custom-schemas/custom-inline-content Example of how to create a BlockNoteSchema that includes custom inline content specifications. ```APIDOC ## Creating a Custom BlockNoteSchema ### Description This example demonstrates how to create a custom BlockNote schema that incorporates your custom inline content specifications. ### Method `BlockNoteSchema.create()` ### Endpoint N/A (Client-side configuration) ### Parameters #### Request Body - **`inlineContentSpecs`** (object) - Required - An object containing the specifications for inline content. - **`defaultInlineContentSpecs`** (object) - Optional - Includes default inline content specifications. - **`mention`** (YourCustomMentionComponent) - Required - Your custom inline content component (e.g., `Mention`). ### Request Example ```typescript import { BlockNoteSchema, defaultInlineContentSpecs } from '@blocknote/core'; // Assuming Mention is your custom inline content component // import Mention from './Mention'; const schema = BlockNoteSchema.create({ inlineContentSpecs: { // enable the default inline content if desired ...defaultInlineContentSpecs, // Add your own custom inline content: mention: Mention, }, }); ``` ### Response N/A (This is a configuration step, not an API call.) ### Note After creating the custom schema, instantiate your editor with this schema as explained on the [Custom Schemas](/docs/features/custom-schemas) page. ``` -------------------------------- ### Apply Custom CSS to BlockNote Source: https://www.blocknotejs.org/docs/react/styling-theming/overriding-css Use the theming/theming-css example to apply custom styles to the editor text and UI components. ```jsx ``` -------------------------------- ### Configure Heading Block Levels Source: https://www.blocknotejs.org/docs/features/blocks Example of creating a heading block specification with restricted levels. ```typescript // Creates a new instance of the default heading block. const heading = createHeadingBlockSpec({ // Sets the block to support only heading levels 1-3. levels: [1, 2, 3], }); ``` -------------------------------- ### Implement Custom Syntax Highlighting Source: https://www.blocknotejs.org/docs/features/blocks/code-blocks Example of implementing custom syntax highlighting in BlockNote by creating a code block spec with a custom highlighter generated by shiki-codegen. ```typescript import { createHighlighter } from "./shiki.bundle.js"; export default function App() { const editor = useCreateBlockNote({ schema: BlockNoteSchema.create().extend({ blockSpecs: { codeBlock: createCodeBlockSpec({ indentLineWithTab: true, defaultLanguage: "typescript", supportedLanguages: { typescript: { name: "TypeScript", aliases: ["ts"], }, }, createHighlighter: () => createHighlighter({ themes: ["light-plus", "dark-plus"], langs: [], }), }), }, }), }); return ; } ``` -------------------------------- ### Implement a Custom Mention Tag Source: https://www.blocknotejs.org/docs/features/custom-schemas/custom-inline-content Example implementation of a custom mention tag using createReactInlineContentSpec. ```typescript const Mention = createReactInlineContentSpec( { type: "mention", propSchema: { user: { default: "Unknown", }, }, content: "none", } as const, { render: (props) => ( ... ), } ); ``` -------------------------------- ### Backend API Route for AI Requests (Next.js) Source: https://www.blocknotejs.org/docs/features/ai/getting-started Set up a backend API route to handle AI requests, forwarding them to an LLM provider using the AI SDK. This example uses Next.js. ```typescript import { openai } from "@ai-sdk/openai"; import { convertToModelMessages, streamText } from "ai"; import { aiDocumentFormats, injectDocumentStateMessages, toolDefinitionsToToolSet, } from "@blocknote/xl-ai/server"; // Allow streaming responses up to 30 seconds export const maxDuration = 30; export async function POST(req: Request) { const { messages, toolDefinitions } = await req.json(); const result = streamText({ model: openai("gpt-4.1"), // see https://ai-sdk.dev/docs/foundations/providers-and-models system: aiDocumentFormats.html.systemPrompt, messages: await convertToModelMessages( injectDocumentStateMessages(messages), ), tools: toolDefinitionsToToolSet(toolDefinitions), toolChoice: "required", }); return result.toUIMessageStreamResponse(); } ``` -------------------------------- ### Integrate Custom AI Menu into BlockNoteView Source: https://www.blocknotejs.org/docs/features/ai/custom-commands Integrates the `CustomAIMenu` component into the Blocknote editor using `AIMenuController`. This example also shows how to include other UI elements like `FormattingToolbarWithAI` and `SuggestionMenuWithAI`. ```tsx {/* Creates a new AIMenu with the default items, as well as our custom ones. */} {/* ...other UI Elements... */} ``` -------------------------------- ### Implement a custom font style Source: https://www.blocknotejs.org/docs/features/custom-schemas/custom-styles Example implementation of a font style using a span element and the provided contentRef. ```typescript export const Font = createReactStyleSpec( { type: "font", propSchema: "string", }, { render: (props) => ( ), } ); ``` -------------------------------- ### BlockNote Dictionary Slash Menu Structure Source: https://www.blocknotejs.org/docs/features/localization Example structure for the `slash_menu` object within the BlockNote dictionary, defining commands available via the '/' input. ```json slash_menu: { paragraph: { title: "Paragraph", subtext: "The body of your document", aliases: ["p", "paragraph"], group: "Basic blocks", }, heading: { title: "Heading 1", subtext: "Top-level heading", aliases: ["h", "heading1", "h1"], group: "Headings", }, // ... more menu items } ``` -------------------------------- ### Custom Paste Handler Implementation Source: https://www.blocknotejs.org/docs/reference/editor/paste-handling Example of intercepting specific clipboard formats and falling back to the default handler if the custom format is not present. ```ts const editor = new BlockNoteEditor({ pasteHandler: ({ event, editor, defaultPasteHandler }) => { if (event.clipboardData?.types.includes("text/my-custom-format")) { // You can do any custom logic here, for example you could transform the clipboard data before pasting it const markdown = customToMarkdown( event.clipboardData.getData("text/my-custom-format"), ); // The editor is able paste markdown (`pasteMarkdown`), HTML (`pasteHTML`), or plain text (`pasteText`) editor.pasteMarkdown(markdown); // We handled the paste event, so return true, returning false will cancel the paste event return true; } // If we didn't handle the paste event, call the default paste handler to do the default behavior return defaultPasteHandler(); }, }); ``` -------------------------------- ### BlockNote Dictionary Placeholders Structure Source: https://www.blocknotejs.org/docs/features/localization Example structure for the `placeholders` object within the BlockNote dictionary, defining text for empty blocks and input fields. ```json placeholders: { default: "Enter text or type '/' for commands", heading: "Heading", bulletListItem: "List", numberedListItem: "List", checkListItem: "List", new_comment: "Write a comment...", edit_comment: "Edit comment...", comment_reply: "Add comment..." } ``` -------------------------------- ### Create Custom Grid Suggestion Menu for Mentions Source: https://www.blocknotejs.org/docs/react/components/grid-suggestion-menus Add a new Grid Suggestion Menu for mentions using the `@` trigger character. This example configures the menu to display user initials and can be further customized with column counts or custom rendering components. ```typescript const editor = useBlockNote({ // ... other props BlockNoteView: ({ children }) => ( { // Fetch and filter users based on query const users = await fetchUsers(query); return users.map((user) => ({ label: user.name, // Render user initials or other relevant info name: user.name.charAt(0), })); }} /> {children} ), }); ``` -------------------------------- ### BlockNote Dictionary UI Elements Structure Source: https://www.blocknotejs.org/docs/features/localization Example structure for UI element translations within the BlockNote dictionary, covering side menu, table handles, and color picker labels. ```json side_menu: { add_block_label: "Add block", drag_handle_label: "Open block menu", }, table_handle: { delete_column_menuitem: "Delete column", add_left_menuitem: "Add column left", // ... more table options }, color_picker: { text_title: "Text", background_title: "Background", colors: { default: "Default", gray: "Gray", // ... more colors } } ``` -------------------------------- ### Create Liveblocks App for BlockNote Collaboration Source: https://www.blocknotejs.org/docs/features/collaboration Use the `create-liveblocks-app` command to quickly set up a BlockNote project with Liveblocks integration for collaboration. Requires a Liveblocks account. ```shell npx create-liveblocks-app@latest --example nextjs-blocknote --api-key ``` -------------------------------- ### Creating a Customizable Block with createReactBlockSpec Source: https://www.blocknotejs.org/docs/features/custom-schemas/custom-blocks Demonstrates how to create a custom block with configurable options, such as syntax highlighting languages for code blocks. This allows for dynamic block behavior based on provided options. ```typescript type CustomBlockConfigOptions = { // Arbitrary options that your block can take, e.g. number of heading levels or // available code syntax highlight languages. ... }; const createCustomBlock = createReactBlockSpec( createBlockConfig((options: CustomBlockConfigOptions) => ({ type: "customBlock" propSchema: ..., content: ..., })), (options: CustomBlockConfigOptions) => ({ render: ..., ... }) ) const options: CustomBlockConfigOptions = { ... }; const schema = BlockNoteSchema.create().extend({ blockSpecs: { // Creates an instance of the custom block and adds it to the schema. customBlock: createCustomBlock(options), }, }); ``` -------------------------------- ### Configure Groq with fetchViaProxy Source: https://www.blocknotejs.org/docs/features/ai/backend-integration Use fetchViaProxy to route requests through a custom proxy URL. The API key is handled by the proxy server rather than the client. ```ts import { createGroq } from "@ai-sdk/groq"; import { fetchViaProxy } from "@blocknote/xl-ai"; const model = createGroq({ fetch: fetchViaProxy( (url) => `${BASE_URL}/proxy?provider=groq&url=${encodeURIComponent(url)}`, ), apiKey: "fake-api-key", // the API key is not used as it's actually added in the proxy server })("llama-3.3-70b-versatile"); ``` -------------------------------- ### Get Cursor Position Source: https://www.blocknotejs.org/docs/reference/editor/cursor-selections Retrieves the current cursor position information. ```typescript getTextCursorPosition(): TextCursorPosition; // Usage const cursorPos = editor.getTextCursorPosition(); console.log("Cursor is in block:", cursorPos.block.id); ``` -------------------------------- ### Set Cursor Position Source: https://www.blocknotejs.org/docs/reference/editor/cursor-selections Moves the cursor to the start or end of a specified block. ```typescript setTextCursorPosition( targetBlock: BlockIdentifier, placement: "start" | "end" = "start" ): void; // Usage editor.setTextCursorPosition(blockId, "start"); editor.setTextCursorPosition(blockId, "end"); ``` -------------------------------- ### Get Current Selection Source: https://www.blocknotejs.org/docs/reference/editor/cursor-selections Retrieves the currently selected blocks or undefined if nothing is selected. ```typescript getSelection(): Selection | undefined; // Usage const selection = editor.getSelection(); if (selection) { console.log("Selected blocks:", selection.blocks.length); } ``` -------------------------------- ### Create a Custom AI Menu Component Source: https://www.blocknotejs.org/docs/features/ai/custom-commands Creates a custom AI menu component that includes the 'Make Informal' command when text is selected. It uses the `AIMenu` component and `getDefaultAIMenuItems` to build the menu. ```tsx import { AIMenu, getDefaultAIMenuItems } from "@blocknote/xl-ai"; function CustomAIMenu() { return ( , aiResponseStatus: | "user-input" | "thinking" | "ai-writing" | "error" | "user-reviewing" | "closed", ) => { if (aiResponseStatus === "user-input") { if (editor.getSelection()) { // When a selection is active (so when the AI Menu is opened via the Formatting Toolbar), // we add our `makeInformal` command to the default items. return [ ...getDefaultAIMenuItems(editor, aiResponseStatus), makeInformal(editor), ]; } else { return getDefaultAIMenuItems(editor, aiResponseStatus); } } // for other states, return the default items return getDefaultAIMenuItems(editor, aiResponseStatus); }} /> ); } ``` -------------------------------- ### Get All Top-Level Blocks Source: https://www.blocknotejs.org/docs/reference/editor/manipulating-content Retrieves a snapshot of all top-level (non-nested) blocks in the editor's document. ```typescript const blocks = editor.document; ``` -------------------------------- ### Load BlockNote Document from JSON Source: https://www.blocknotejs.org/docs/foundations/supported-formats Initialize the BlockNote editor with existing content by passing an array of Block objects to the `initialContent` prop during editor creation. ```tsx import { useCreateBlockNote } from "@blocknote/react"; import type { Block } from "@blocknote/core"; import { BlockNoteView } from "@blocknote/mantine"; export default function App({ initialContent, }: { initialContent?: Block[]; }) { const editor = useCreateBlockNote({ initialContent, }); return ; } ``` -------------------------------- ### Numbered List Item Source: https://www.blocknotejs.org/docs/features/blocks/list-types Represents an item in a numbered list. It can optionally specify its starting number. ```APIDOC ## Numbered List Item ### Description A numbered list item is a list item that is numbered. ### Type & Props ```typescript type NumberedListItemBlock = { id: string; type: "numberedListItem"; props: DefaultProps & { start?: number; }; content: InlineContent[]; children: Block[]; }; ``` `start:` The number of this list item. If not provided, it defaults to `1`, or is incremented from the previous item. ``` -------------------------------- ### Generate Custom Syntax Highlighter Source: https://www.blocknotejs.org/docs/features/blocks/code-blocks Command to generate a Shiki syntax highlighter bundle for specific languages and themes using the shiki-codegen CLI. ```bash npx shiki-codegen --langs javascript,typescript,vue --themes light-plus,dark-plus --engine javascript --precompiled ./shiki.bundle.ts ``` -------------------------------- ### Define Numbered List Item Type Source: https://www.blocknotejs.org/docs/features/blocks/list-types Represents a numbered list item block with an optional start property. ```typescript type NumberedListItemBlock = { id: string; type: "numberedListItem"; props: DefaultProps & { start?: number; }; content: InlineContent[]; children: Block[]; }; ``` -------------------------------- ### Create a basic BlockNote editor Source: https://www.blocknotejs.org/docs/getting-started Implementation of a React component using the useCreateBlockNote hook and BlockNoteView to render the editor. ```tsx import React from "react"; import { useCreateBlockNote } from "@blocknote/react"; // Or, you can use ariakit, shadcn, etc. import { BlockNoteView } from "@blocknote/mantine"; // Default styles for the mantine editor import "@blocknote/mantine/style.css"; // Include the included Inter font import "@blocknote/core/fonts/inter.css"; export default function MyEditor() { // Create a new editor instance const editor = useCreateBlockNote(); // Render the editor return ; } ``` -------------------------------- ### Create Schema from Scratch with Custom Elements Source: https://www.blocknotejs.org/docs/features/custom-schemas Create a new schema from scratch by passing custom blocks, inline content, or styles directly to `BlockNoteSchema.create`. This is useful for minimal schemas. ```typescript const schema = BlockNoteSchema.create({ blockSpecs: { paragraph: defaultBlockSpecs.paragraph, customBlock: CustomBlock, ... }, inlineContentSpecs: { text: defaultInlineContentSpecs.text, customInlineContent: CustomInlineContent, ... }, styleSpecs: { bold: defaultStyleSpecs.bold, customStyle: CustomStyle, ... }, }); ``` -------------------------------- ### Get Selected Link URL Source: https://www.blocknotejs.org/docs/reference/editor/manipulating-content Retrieves the URL of the last link in the current selection. Returns undefined if no links are selected. ```APIDOC ## getSelectedLinkUrl ### Description Returns the URL of the last link in the current selection, or `undefined` if no links are selected. ### Method Signature ```typescript getSelectedLinkUrl(): string | undefined ``` ### Usage Example ```typescript const linkUrl = editor.getSelectedLinkUrl(); if (linkUrl) { console.log("Selected link URL:", linkUrl); // Open link in new tab window.open(linkUrl, "_blank"); } else { console.log("No link selected"); } ``` ``` -------------------------------- ### Initialize and Use ReactEmailExporter Source: https://www.blocknotejs.org/docs/features/export/email Create an instance of the exporter and convert editor blocks into a React-Email document. ```typescript import { ReactEmailExporter, reactEmailDefaultSchemaMappings, } from "@blocknote/xl-email-exporter"; // Create the exporter const exporter = new ReactEmailExporter( editor.schema, reactEmailDefaultSchemaMappings, ); // Convert the blocks to a react-email document const html = await exporter.toReactEmailDocument(editor.document); // Use react-email to write to file: await ReactEmail.render(html, `filename.html`); ``` -------------------------------- ### Initialize and Use ODTExporter Source: https://www.blocknotejs.org/docs/features/export/odt Create an instance of the ODTExporter and convert editor blocks into an ODT document. ```typescript import { ODTExporter, odtDefaultSchemaMappings, } from "@blocknote/xl-odt-exporter"; // Create the exporter const exporter = new ODTExporter(editor.schema, odtDefaultSchemaMappings); // Convert the blocks to a ODT document (Blob) const odtDocument = await exporter.toODTDocument(editor.document); ``` -------------------------------- ### Get Selected Link URL Source: https://www.blocknotejs.org/docs/reference/editor/manipulating-content Retrieves the URL of the last link in the current selection. Opens the link in a new tab if found. ```typescript const linkUrl = editor.getSelectedLinkUrl(); if (linkUrl) { console.log("Selected link URL:", linkUrl); // Open link in new tab window.open(linkUrl, "_blank"); } else { console.log("No link selected"); } ``` -------------------------------- ### Get Specific Block Information Source: https://www.blocknotejs.org/docs/reference/editor/manipulating-content Fetches a specific block, its previous sibling, its next sibling, or its parent block using a BlockIdentifier. ```typescript // Single block getBlock(blockIdentifier: BlockIdentifier): Block | undefined // Previous block getPrevBlock(blockIdentifier: BlockIdentifier): Block | undefined // Next block getNextBlock(blockIdentifier: BlockIdentifier): Block | undefined // Parent block getParentBlock(blockIdentifier: BlockIdentifier): Block | undefined ``` ```typescript const block = editor.getBlock("block-123"); const prevBlock = editor.getPrevBlock("block-123"); const nextBlock = editor.getNextBlock("block-123"); const parentBlock = editor.getParentBlock("nested-block-123"); ``` -------------------------------- ### Configure HeadingBlock Options Source: https://www.blocknotejs.org/docs/features/blocks/typography Configuration options for customizing heading block behavior. ```typescript type HeadingBlockOptions = Partial<{ defaultLevel?: number; levels?: number[]; allowToggleHeadings?: boolean; }>; ``` -------------------------------- ### YjsThreadStore Implementation Source: https://www.blocknotejs.org/docs/features/collaboration/comments Use YjsThreadStore for direct Yjs-based comment storage, suitable for simple collaborative setups where all users have write access to the document. ```tsx import { YjsThreadStore } from "@blocknote/core/yjs"; const threadStore = new YjsThreadStore( userId, // The active user's ID yDoc.getMap("threads"), // Y.Map to store threads new DefaultThreadStoreAuth(userId, "editor"), // Authorization information, see below ); ``` -------------------------------- ### Get Selected Text Source: https://www.blocknotejs.org/docs/reference/editor/manipulating-content Retrieve the currently selected text as a plain string. Useful for operations like copying or analyzing user input. ```typescript const selectedText = editor.getSelectedText(); console.log("Selected text:", selectedText); // Example: Copy selected text to clipboard if (selectedText) { navigator.clipboard.writeText(selectedText); } ``` -------------------------------- ### Integrate BlockNote with react-i18next Source: https://www.blocknotejs.org/docs/features/localization Integrate BlockNote with `react-i18next` by using the `useTranslation` hook to get the current language and passing the corresponding locale to the editor. ```tsx import { useCreateBlockNote, BlockNoteView } from "@blocknote/react"; import { useTranslation } from "react-i18next"; import * as locales from "@blocknote/core/locales"; function I18nEditor() { const { i18n } = useTranslation(); const editor = useCreateBlockNote({ dictionary: locales[i18n.language as keyof typeof locales] || locales.en, }); return ; } ``` -------------------------------- ### Create BlockNote Editor with AI Extension Source: https://www.blocknotejs.org/docs/features/ai/getting-started Set up the BlockNote editor with the AI Extension enabled, including default translations and a default chat transport. ```typescript import { createBlockNoteEditor } from "@blocknote/core"; import { BlockNoteAIExtension } from "@blocknote/xl-ai"; import { en } from "@blocknote/core/locales"; import { en as aiEn } from "@blocknote/xl-ai/locales"; import { AIExtension } from "@blocknote/xl-ai"; import "@blocknote/xl-ai/style.css"; // add the AI stylesheet const editor = createBlockNoteEditor({ dictionary: { ...en, ai: aiEn, // add default translations for the AI extension }, extensions: [ AIExtension({ transport: new DefaultChatTransport({ api: `/api/chat`, }), }), ], // ... other editor options }); ``` -------------------------------- ### Configure Exporter Options Source: https://www.blocknotejs.org/docs/features/export/odt Define custom options for file resolution and color settings during exporter initialization. ```typescript const defaultOptions = { // a function to resolve external resources in order to avoid CORS issues // by default, this calls a BlockNote hosted server-side proxy to resolve files resolveFileUrl: corsProxyResolveFileUrl, // the colors to use in the ODT for things like highlighting, background colors and font colors. colors: COLORS_DEFAULT, // defaults from @blocknote/core }; ``` -------------------------------- ### Get Active Styles Source: https://www.blocknotejs.org/docs/reference/editor/manipulating-content Returns the active text styles at the current cursor position or selection. Useful for dynamic UI elements or conditional formatting. ```typescript const activeStyles = editor.getActiveStyles(); console.log("Active styles:", activeStyles); // Example: Check if text is bold if (activeStyles.bold) { ``` -------------------------------- ### Configure Exporter Options Source: https://www.blocknotejs.org/docs/features/export/email Set custom file resolution and color configurations for the exporter. ```typescript const defaultOptions = { // a function to resolve external resources in order to avoid CORS issues // by default, this calls a BlockNote hosted server-side proxy to resolve files resolveFileUrl: corsProxyResolveFileUrl, // the colors to use in the email for things like highlighting, background colors and font colors. colors: COLORS_DEFAULT, // defaults from @blocknote/core }; ``` -------------------------------- ### Removing a Slash Menu Item Source: https://www.blocknotejs.org/docs/react/components/suggestion-menus Remove a specific item from the slash menu by filtering the array of items. This example removes the 'Heading 1' item. ```typescript const items = getDefaultReactSlashMenuItems(editor).filter( (item) => item.title !== "Heading 1", ); ``` -------------------------------- ### Initialize CommentsExtension in BlockNote Source: https://www.blocknotejs.org/docs/features/collaboration/comments Configure the CommentsExtension by providing a threadStore, resolveUsers function, and optionally a schema. Ensure real-time collaboration is enabled. ```tsx import { withCollaboration } from "@blocknote/core/yjs"; const editor = useCreateBlockNote( withCollaboration({ extensions: [ CommentsExtension({ // See below. threadStore: ..., // Return user information for the given userIds (see below). resolveUsers: async (userIds: string[]) => { ... }, // Optional, can be left undefined schema: BlockNoteSchema.create(...) }), ... ], collaboration: { // See real-time collaboration docs ... }, ... }), ); ``` -------------------------------- ### Customize Emoji Picker Columns Source: https://www.blocknotejs.org/docs/react/components/grid-suggestion-menus To change the default number of columns for the Emoji Picker, pass the `columns` prop to `GridSuggestionMenuController`. This example sets it to 5 columns. ```typescript const editor = useBlockNote({ // ... other props BlockNoteView: ({ children }) => ( {children} ), }); ``` -------------------------------- ### Basic PDF Export Source: https://www.blocknotejs.org/docs/features/export/pdf Create a PDFExporter instance and convert the editor's document to a React-PDF document, then render it to a file. ```typescript import { PDFExporter, pdfDefaultSchemaMappings, } from "@blocknote/xl-pdf-exporter"; import * as ReactPDF from "@react-pdf/renderer"; // Create the exporter const exporter = new PDFExporter(editor.schema, pdfDefaultSchemaMappings); // Convert the blocks to a react-pdf document const pdfDocument = await exporter.toReactPDFDocument(editor.document); // Use react-pdf to write to file: await ReactPDF.render(pdfDocument, `filename.pdf`); ``` -------------------------------- ### Create BlockNoteSchema with Custom Inline Content Source: https://www.blocknotejs.org/docs/features/custom-schemas/custom-inline-content Use `BlockNoteSchema.create` to define your editor's schema, including custom inline content specifications like 'mention'. Ensure you import `defaultInlineContentSpecs` if you want to include default inline content types. ```typescript const schema = BlockNoteSchema.create({ inlineContentSpecs: { // enable the default inline content if desired ...defaultInlineContentSpecs, // Add your own custom inline content: mention: Mention, }, }); ``` -------------------------------- ### Configure BlockNote for Collaboration with Yjs Source: https://www.blocknotejs.org/docs/features/collaboration Use the `withCollaboration` helper to integrate Yjs for real-time editing. Configure the Yjs provider, document fragment, and user information. ```typescript import * as Y from "yjs"; import { WebrtcProvider } from "y-webrtc"; import { withCollaboration } from "@blocknote/core/yjs"; // ... const doc = new Y.Doc(); const provider = new WebrtcProvider("my-document-id", doc); // setup a yjs provider (explained below) const editor = useCreateBlockNote( withCollaboration({ // ... collaboration: { // The Yjs Provider responsible for transporting updates: provider, // Where to store BlockNote data in the Y.Doc: fragment: doc.getXmlFragment("document-store"), // Information (name and color) for this user: user: { name: "My Username", color: "#ff0000", }, // When to show user labels on the collaboration cursor. Set by default to // "activity" (show when the cursor moves), but can also be set to "always". showCursorLabels: "activity", }, // ... }), ); ``` -------------------------------- ### YJS Utilities Import Source: https://www.blocknotejs.org/docs/reference/editor/yjs-utilities Import the necessary YJS utility functions from the @blocknote/core/yjs package. ```APIDOC ## Import YJS Utilities ### Description Import the necessary YJS utility functions for converting between BlockNote blocks and YJS documents. ### Code ```typescript import { blocksToYDoc, blocksToYXmlFragment, yDocToBlocks, yXmlFragmentToBlocks, } from "@blocknote/core/yjs"; ``` ``` -------------------------------- ### Get Stream Tools Provider for LLM Operations Source: https://www.blocknotejs.org/docs/features/ai/reference Obtain the tools an LLM can use to interpret and modify the document. Typically, use `aiDocumentFormats.html.getStreamToolsProvider(...)` for HTML documents. ```typescript /** Return a provider for the stream tools available to the LLM */ type getStreamToolsProvider = ( ``` -------------------------------- ### Export BlockNote Content to HTML Source: https://www.blocknotejs.org/docs/features/import Use the `editor.blocksToHTMLLossy` method to convert BlockNote blocks into an HTML string for migration to other editors. Server-side processing details are available in the server-side guide. ```typescript const htmlContent = editor.blocksToHTMLLossy(); ``` -------------------------------- ### Initialize Editor with Custom Schema Source: https://www.blocknotejs.org/docs/features/custom-schemas Pass your created schema instance to the `schema` option when initializing the BlockNote editor using `useCreateBlockNote` or `BlockNoteEditor.create`. ```typescript const editor = useCreateBlockNote({ schema, }); ``` -------------------------------- ### AIExtension Configuration Source: https://www.blocknotejs.org/docs/features/ai/reference Defines how to register the AIExtension within the useCreateBlockNote hook and the available configuration options. ```APIDOC ## AIExtension ### Description Registers the AI extension to the editor. It accepts configuration options for the agent cursor and request helpers. ### Parameters #### Request Body - **agentCursor** (object) - Optional - The name and color of the agent cursor when the AI is writing. - **transport** (ChatTransport) - Optional - Transport used by the AI SDK to send requests. - **chatProvider** (function) - Optional - Custom provider for the AI SDK Chat instance. - **streamToolsProvider** (StreamToolsProvider) - Optional - Customizes available stream tools for the LLM. - **chatRequestOptions** (ChatRequestOptions) - Optional - Extra headers/body/metadata forwarded to the AI SDK. - **documentStateBuilder** (DocumentStateBuilder) - Optional - Builds the serializable document state for the backend. ``` -------------------------------- ### Inserting a Slash Menu Item Source: https://www.blocknotejs.org/docs/react/components/suggestion-menus Insert a custom item into the slash menu at a specific position using array splice. This example inserts an item after the default 'Heading 1' item. ```typescript const items = getDefaultReactSlashMenuItems(editor); const headingIndex = items.findIndex((item) => item.title === "Heading 1"); items.splice(headingIndex + 1, 0, insertHelloWorldItem(editor)); ``` -------------------------------- ### Define a Custom BlockNote Extension Source: https://www.blocknotejs.org/docs/features/extensions Use `createExtension` to define a new extension. Configure keyboard shortcuts, input rules, ProseMirror plugins, or TipTap extensions. ```typescript type Extension = { key: string; keyboardShortcuts?: Record< string, (ctx: { editor: BlockNoteEditor; }) => boolean >; inputRules?: { find: RegExp; replace: (props: { match: RegExpMatchArray; range: { from: number; to: number }; editor: BlockNoteEditor; }) => PartialBlock | undefined; }[]; plugins?: Plugin[]; tiptapExtensions?: AnyExtension[]; } const CustomExtension = createExtension({ key: "customBlockExtension", keyboardShortcuts: ..., inputRules: ..., plugins: ..., tiptapExtensions: ..., }); ``` -------------------------------- ### Create Link Source: https://www.blocknotejs.org/docs/reference/editor/manipulating-content Creates a new link, optionally replacing the currently selected text. ```APIDOC ## createLink ### Description Creates a new link, optionally replacing the currently selected text. ### Method Signature ```typescript createLink(url: string, text?: string): void ``` ### Parameters - **url** (string) - Required - The URL for the link. - **text** (string) - Optional - The text to display for the link. If omitted, the currently selected text is used. ### Usage Example ```typescript // Create link from selected text editor.createLink("https://blocknotejs.org"); // Create link with custom text editor.createLink("https://blocknotejs.org", "Visit BlockNote"); // Create link with empty URL (removes link) editor.createLink(""); ``` ``` -------------------------------- ### Customize BlockNote Text Strings Source: https://www.blocknotejs.org/docs/features/localization Customize specific text strings by extending an existing dictionary (e.g., English). This example shows how to modify placeholders and slash menu item text. ```tsx import { useCreateBlockNote, BlockNoteView } from "@blocknote/react"; import { en } from "@blocknote/core/locales"; function CustomEditor() { const editor = useCreateBlockNote({ dictionary: { ...en, placeholders: { ...en.placeholders, default: "Start typing your story...", heading: "Enter your title here", emptyDocument: "Begin your document", }, slash_menu: { ...en.slash_menu, paragraph: { ...en.slash_menu.paragraph, title: "Text Block", subtext: "Regular text content", }, }, }, }); return ; } ``` -------------------------------- ### Custom Mappings for Custom Schemas Source: https://www.blocknotejs.org/docs/features/export/pdf Define custom mappings for BlockNote elements when using a custom schema or overriding default conversions. This example shows how to map a custom block type. ```typescript import { PDFExporter, pdfDefaultSchemaMappings } from "@blocknote/xl-pdf-exporter"; import { Text } from "@react-pdf/renderer"; new PDFExporter(schema, { blockMapping: { ...pdfDefaultSchemaMappings.blockMapping, myCustomBlock: (block, exporter) => { return My custom block; }, }, inlineContentMapping: pdfDefaultSchemaMappings.inlineContentMapping, styleMapping: pdfDefaultSchemaMappings.styleMapping, }); ``` -------------------------------- ### Video Block Options Source: https://www.blocknotejs.org/docs/features/blocks/embeds Configuration options for video embeds, allowing customization of the block's icon. ```typescript type VideoBlockOptions = { icon?: string; }; ``` -------------------------------- ### Create a BlockNote Editor Instance Source: https://www.blocknotejs.org/docs/getting-started/editor-setup The useCreateBlockNote hook instantiates the editor and its state. It accepts optional configuration options and a React dependency array. ```tsx declare function useCreateBlockNote( options?: BlockNoteEditorOptions, deps?: React.DependencyList, ): BlockNoteEditor; ``` -------------------------------- ### Customize Email Output Source: https://www.blocknotejs.org/docs/features/export/email Configure email preview, header, footer, head elements, container, and body styles during document conversion. ```tsx import React from "react"; import { ReactEmailExporter, reactEmailDefaultSchemaMappings, } from "@blocknote/xl-email-exporter"; import { BlockNoteEditor } from "@blocknote/core"; import { Text, Container } from "@react-email/components"; const editor = BlockNoteEditor.create(); // ---cut--- const exporter = new ReactEmailExporter( editor.schema, reactEmailDefaultSchemaMappings, ); const html = await exporter.toReactEmailDocument(editor.document, { preview: "This is a preview of the email content", header: Header, footer: Footer, head: My email, container: ({ children }) => {children}, // These are the default body styles that are set by default bodyStyles: { fontFamily: "'SF Pro Display', -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Helvetica Neue', Arial, sans-serif", fontSize: "16px", lineHeight: "1.5", color: "#333", }, }); ``` -------------------------------- ### Custom Slash Menu with getItems Source: https://www.blocknotejs.org/docs/react/components/suggestion-menus Replace the default slash menu by setting `slashMenu={false}` on BlockNoteView and adding a SuggestionMenuController with a custom `getItems` function. This example appends a custom item to the default list. ```typescript getItems={async (query) => filterSuggestionItems( [ insertHelloWorldItem(editor), // Shown first ...getDefaultReactSlashMenuItems(editor), // Shown after ], query, ) } ``` -------------------------------- ### Custom Inline Content Configuration Source: https://www.blocknotejs.org/docs/features/custom-schemas/custom-inline-content Configuration options for custom inline content, including rendering, drag-and-drop, and HTML parsing. ```APIDOC ## Inline Content Configuration Options ### `contentRef` - **Type**: React `ref` - **Description**: A ref to mark the editable element within inline content. Only available if `content` is set to `"styled"` in your inline content configuration. ### `draggable` - **Type**: `boolean` - **Default**: `false` - **Description**: Specifies whether the inline content can be dragged. If `true`, the element should have a `data-drag-handle` attribute on the DOM element that functions as the drag handle. ### `toExternalHTML` - **Type**: `(props: any) => React.ReactNode` - **Description**: A component used for exporting inline content to HTML outside of BlockNote (e.g., for clipboard copying). If not defined, BlockNote uses the `render` prop for HTML conversion. Takes the same props as `render`. Note: This component renders in a separate React root, so hooks relying on React Contexts may not work. ### `parse` - **Type**: `(element: HTMLElement) => any | undefined` - **Description**: A function that defines how to parse HTML content into your custom inline content when pasting from the clipboard. If the HTML element should be parsed into your custom inline content, return the props the block should receive. Otherwise, return `undefined`. ### `meta?.draggable` - **Type**: `boolean` - **Description**: An alternative way to specify if the inline content should be draggable. Your component should return an HTML inline element. ``` -------------------------------- ### Manage event cleanup Source: https://www.blocknotejs.org/docs/reference/editor/events Demonstrates how to store and invoke cleanup functions returned by event listeners. ```typescript // Set up event listeners const cleanupOnChange = editor.onChange((editor, { getChanges }) => { console.log("Content changed"); }); const cleanupOnSelection = editor.onSelectionChange((editor) => { console.log("Selection changed"); }); // Later, clean up event listeners cleanupOnChange(); cleanupOnSelection(); ``` -------------------------------- ### AIExtension Instance Methods Source: https://www.blocknotejs.org/docs/features/ai/reference Methods and state accessors available on the AIExtension instance to control the AI menu and document interactions. ```APIDOC ## AIExtension Instance Methods ### Description Methods exposed by the extension instance to manage AI state, menu visibility, and document modifications. ### Methods - **invokeAI(opts)**: Executes an LLM call. - **openAIMenuAtBlock(blockID)**: Opens the AI menu at a specific block. - **closeAIMenu()**: Closes the AI menu. - **acceptChanges()**: Accepts LLM modifications. - **rejectChanges()**: Rejects LLM modifications. - **retry()**: Retries a failed LLM call. - **abort(reason)**: Aborts the current request. ``` -------------------------------- ### Custom Block Mapping for DOCX Export Source: https://www.blocknotejs.org/docs/features/export/docx Define custom mappings for BlockNote schema elements to docxjs elements when using a custom schema or overriding default conversions. This example shows how to map a custom block type named 'myCustomBlock'. ```typescript import { DOCXExporter, docxDefaultSchemaMappings, } from "@blocknote/xl-docx-exporter"; import { Paragraph, TextRun } from "docx"; new DOCXExporter(schema, { blockMapping: { ...docxDefaultSchemaMappings.blockMapping, myCustomBlock: (block, exporter) => { return new Paragraph({ children: [ new TextRun({ text: "My custom block", }), ], }); }, }, inlineContentMapping: docxDefaultSchemaMappings.inlineContentMapping, styleMapping: docxDefaultSchemaMappings.styleMapping, }); ``` -------------------------------- ### Editor Lifecycle Events Source: https://www.blocknotejs.org/docs/reference/editor/events Callbacks for tracking the editor's mounting and unmounting lifecycle stages. ```APIDOC ## onMount ### Description Triggered when the editor has been successfully mounted. ### Method `editor.onMount(callback)` ## onUnmount ### Description Triggered when the editor has been unmounted. ### Method `editor.onUnmount(callback)` ``` -------------------------------- ### Create Link Source: https://www.blocknotejs.org/docs/reference/editor/manipulating-content Creates a new link, optionally replacing the currently selected text with a custom text. An empty URL removes the link. ```typescript // Create link from selected text editor.createLink("https://blocknotejs.org"); // Create link with custom text editor.createLink("https://blocknotejs.org", "Visit BlockNote"); // Create link with empty URL (removes link) editor.createLink(""); ``` -------------------------------- ### Audio Block Options Source: https://www.blocknotejs.org/docs/features/blocks/embeds Configuration options for audio embeds, allowing customization of the block's icon. ```typescript type AudioBlockOptions = { icon?: string; }; ``` -------------------------------- ### InvokeAI Options for LLM Requests Source: https://www.blocknotejs.org/docs/features/ai/reference Configure LLM requests using InvokeAIOptions, specifying the user prompt, whether to use editor selection, and options to automatically delete empty cursor blocks. Helpers can be overridden per request. ```typescript type InvokeAIOptions = { /** The user prompt */ userPrompt: string; /** Whether to use the editor selection for the LLM call (default: true) */ useSelection?: boolean; /** * If the user's cursor is in an empty paragraph, automatically delete it when the AI starts writing. * Used when typing `/ai` in an empty block. (default: true) */ deleteEmptyCursorBlock?: boolean; } & AIRequestHelpers; // Optionally override helpers per request ```