Code Block example for BlockNote
BlockNote is a opensource Block-Based rich text editor. What you see here is built on BlockNote and it allows to easily integrate text editors into your project. After going through some research, I found that this is a great text editor to use for my project on building my blog for the ease of implementation, as they claimed that 'it just works.' BlockNote came with most of the basic features needed for rich text editor and it has the modern look and feel of the text editor from Notion, one of the famous note-taking app out there, that there is not much additional works needed to make it better. Since my first post about creating my own blog, I soon encountered a significant challenge with BlockNote: it does not support code blocks out of the box. As I will be uploading posts heavy on codebase, having a code block feature was essential. After navigating through various GitHub issues, Discord threads, and countless Google searches, I finally found an approach that worked for me. If you're reading this, I assume you've faced the same hurdle, and I hope my solution can help you too. To make it easier for others, I also created a pull request on BlockNote to add an example on their website, making it more accessible for everyone. If you’ve already set up BlockNote , feel free to skip this section. Otherwise, follow the official to get started. Once set, Let's install necessary packages: After you finish installing, you will have below file structures: Let's create a folder called components and create three files: Once your project is ready, let's remove any default codes on app/page.txt to start with fresh. The code will import BlockNote App from components and load it into the main page. If you have an existing project, just import the App into necessary location. This file will contain the main codebase for setting up BlockNote editor and import custom code block into the editor. Let's import all necessary components first. Since it is a client side component, you need to declare that it's client component at the top of the file. We will then going to create schema for the block specs. We will use the default BlockNote's schema and extend with default schema with the code block. To make the Code block selectable through slash menu, Let's create insertCodeBlock component and define the configuration for the block. The title is the text used with slash menu inside BlockNote. This allows the Code block to appear when you type /code. We are going to assign it into Others group as it's a custom block, and we are going to use the Code icon from Lucide-react package. Additionally we are going to provide subtext which will be appeared below title to give more context on what this block do. Lastly, we are going to create the main App component for the BlockNote and return it so that we can import on other components to show the BlockNote editor. If you finish until now and try running the code, you will see an error message. This is expected and the reason is because we have not implemented components/Code.tsx file. Let's go ahead and implement the Code.tsx file now. This file is the main codebase for the Code block extension. Here, we will use React CodeMirror package to create the code block while let BlockNote to manage the code block content. additionally, we are going to create a drop down option to select which language to use for syntax highlighting. Let's import all the necessary components again on components/Code.tsx file. This will be a client component as well so please include 'use client' at the top of the file. We will now going to create the Code Block. We are going to call this codeBlock . This needs to match with the type above for insertCodeBlock on components/App.tsx file. If you set it to something else other than codeBlock , please make sure that they match. We are going to add two more props and keep track of it: data and language. data - it will be used to keep track of the contents of the editor. language - it will keep track of the currently selected language. Let's set the default value be "javascript," and all available languages can be found from " langNames " from package "@uiw/codemirror-extensions-langs" I also imported 'material' theme from CodeMirror for the editor. If you want to change to different theme, you can find all available styles here:
When you are done and run the project with npm run dev , you will be able to see it running on localhost:3000 (by default). with below screen. This editor seems fine to use, but there are some rooms to improve in terms of the styling. Before we go and add the feature to select style, let's go ahead and create styles.css file in the same directory. This file will contains rules on how the editor should be look to you. If you add this file, you will be able to see that the editor's appearance has changed like below. The style looks better then before and we now need to add a feature to select, browse, and search which language to use for syntax highlighting. Since Mantine UI, the component UI library used for BlockNote, already comes with search drop down component, let's use this to list out the available language for syntax highlighting. The search drop down component keeps track of the selected value through React state. Since State cannot used inside BlockNote's render function, we need to create a new component and call this new component inside the render. that way the state can still be used for the component and we can safely use the component to list the available language. Since this component will use the default value for the language and BlockNote need to capture any changes on the language, let's pass the props from BlockNote to this component. To do so, we need to create a type for the props since we are using typescript. we can get the props from BlockNote and we need to extend to add the two props, data and language. I placed below code between import statements and the Code editor component. The default value is set to the BlockNote's default value we set for language , and we update the BlockNote's language when an event to change selected variabled is triggered. After you add the selectDropDownSearch component, you won't see any changes on the editor. This is because I commented out the lines for this component on the editor. Let's scroll down to the Code component, and uncomment below code block and save for the effect to take place. After you successfully follow it all, you will see the working editor with language selecting for syntax highlighting as well. By following the steps outlined in this post, you’ve successfully implemented the code block feature in BlockNote with syntax highlighting using codemirror. With the code block, you can display code snippets into your BlockNote based application, which is one of the crutial feature if the purpose of the app is to cover technical posts.
Stay tuned for the next post, where I’ll cover how to change the language for syntax highlighting.