S

Sajiron

3 min readPublished on Jan 29, 2025

Setting Up BlockNote.js in a Next.js Project and Customizing Code Block Language

A_modern_code_editor_setup_with_BlockNote.js_insid.jpg

Introduction

BlockNote.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.

Prerequisites

Before we begin, ensure you have the following installed:

Node.js (v16+ recommended)

Next.js (v13+ recommended)

@blocknote/react, @blocknote/core, and @blocknote/mantine

Installation

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

Creating the BlockNote Editor Component

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;

Lazy Loading the Editor in Next.js

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.

How Customizing the Code Block Works

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.

Conclusion

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.