Sajiron
Published on Jan 29, 2025BlockNote.js is a powerful and extensible block-based editor built for React. It allows for seamless integration into Next.js applications with features like rich text editing, code blocks, and file uploads.
In this tutorial, we will walk through setting up BlockNote.js in a Next.js project and customizing the default language for code blocks.
Before we begin, ensure you have the following installed:
Node.js (v16+ recommended)
Next.js (v13+ recommended)
@blocknote/react
, @blocknote/core
, and @blocknote/mantine
To get started, install the necessary dependencies by running:
npm install @blocknote/react @blocknote/core @blocknote/mantine
If you are using yarn
or pnpm
, use:
yarn add @blocknote/react @blocknote/core @blocknote/mantine
pnpm add @blocknote/react @blocknote/core @blocknote/mantine
Now, let's create a React component for the BlockNote editor.
Create a new file Editor.tsx
inside your components folder and add the following code:
'use client';
import React from 'react';
import { useCreateBlockNote } from '@blocknote/react';
import {
Block,
BlockNoteSchema,
CodeBlock,
customizeCodeBlock,
defaultBlockSchema,
defaultBlockSpecs,
} from '@blocknote/core';
import { BlockNoteView } from '@blocknote/mantine';
import { API_ROUTE } from '@/constants/routes';
interface Props {
initialContent?: Block[];
onChange?: (content: Block[]) => void;
}
// Function to handle file uploads
const uploadFile = async (file: File): Promise<string> => {
const formData = new FormData();
formData.append('file', file);
const response = await fetch(API_ROUTE.BLOGS_UPLOAD, {
method: 'POST',
body: formData,
});
if (!response.ok) {
throw new Error('Failed to upload file');
}
const { url } = await response.json();
return url;
};
const Editor: React.FC<Props> = ({ initialContent, onChange }) => {
// Customizing the default language for code blocks
const customCodeBlock = customizeCodeBlock({
defaultLanguage: 'javascript', // Setting JavaScript as the default language
supportedLanguages: ['javascript', 'python', 'typescript', 'java', 'csharp'],
});
// Extending the BlockNote schema with a custom code block
const schema = BlockNoteSchema.create({
...defaultBlockSchema,
blockSpecs: {
...defaultBlockSpecs,
codeBlock: {
...customCodeBlock,
config: CodeBlock.config,
},
},
});
const editor = useCreateBlockNote({
initialContent,
uploadFile,
schema,
});
return <BlockNoteView editor={editor} onChange={() => onChange?.(editor.document)} />;
};
export default Editor;
Since BlockNote.js uses the browser API, it should only be loaded on the client side. We can dynamically import the editor component using Next.js dynamic imports.
Create a new file EditorLoader.tsx
and add:
'use client';
import dynamic from 'next/dynamic';
export default dynamic(() => import('./Editor'), { ssr: false });
Now, wherever you want to use the editor, import EditorLoader.tsx
instead of Editor.tsx
to ensure the editor only loads on the client side.
In the customizeCodeBlock
function, we override the default language for code blocks by setting:
const customCodeBlock = customizeCodeBlock({
defaultLanguage: 'javascript',
supportedLanguages: ['javascript', 'python', 'typescript', 'java', 'csharp'],
});
This ensures that whenever a new code block is inserted, JavaScript is selected as the default language, and users can switch between the specified supported languages.
We successfully set up BlockNote.js in a Next.js project, added file upload functionality, and customized the default language for code blocks. This setup provides a robust and flexible rich-text editing experience for your Next.js application.