### 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
```