Search code examples
javascriptwysiwygtiptap

How do you highlight codeblock with tiptap?


Is there a way to highlight code when using TipTap?

Using the default simple editor I can create block of code when using three backticks but, those are not highlighted.

import { Editor } from '@tiptap/core';
import StarterKit from '@tiptap/starter-kit';
import Highlight from '@tiptap/extension-highlight';
import Typography from '@tiptap/extension-typography';

new Editor({
            element: element,
            extensions: [StarterKit, Highlight, Typography],
            content: html,
            onTransaction: () => {
                // force re-render so `editor.isActive` works as expected
                editor = editor;
            },
            editorProps: {
                attributes: {
                    class: 'focus:outline-none',
                },
            }
        });

Solution

  • I followed @lakshya-thakur answer and used the code-block-lowlight extension.

    However, the documentation is outdated or at least did not worked out at ouf the box with SvelteKit / Vite. Therefore here the detailed solution.

    1. Install the extention
    npm i lowlight @tiptap/extension-code-block-lowlight
    
    1. Import the extension
    import { CodeBlockLowlight } from '@tiptap/extension-code-block-lowlight';
    
    1. Here it differs from the documentation. Import a wrapper to create lowlight and the languages you which to load. You can either import all languages, specific languages or as in this example only a subset of the most common languages.
    import { common, createLowlight } from 'lowlight';
    
    1. To create the extension both those imports.
    CodeBlockLowlight.configure({
            lowlight: createLowlight(common)
        })
    
    1. Adding this extension in addition to the starter kit will results in TipTap throwing a warning Duplicate extension names found: ['blockCode'] at runtime, therefore the block code extension included in the starter kit should be disabled.
    StarterKit.configure({
            codeBlock: false
        })
        
    

    All together the coudl look like:

    new Editor({
                    element: element,
                    extensions:[
                        StarterKit.configure({
                            codeBlock: false
                        }),
                        CodeBlockLowlight.configure({
                            lowlight: createLowlight(common)
                        })
                    ],
                    content,
                    onTransaction: () => {
                        // force re-render so `editor.isActive` works as expected
                        editor = editor;
                    },
                }) 
    
    1. Finally, the code won't be highlighted without CSS. Therefore you should also define some styles.
    pre {
            background: #0D0D0D;
            color: #FFF;
            font-family: 'JetBrainsMono', monospace;
            padding: 0.75rem 1rem;
            border-radius: 0.5rem;
    
            code {
                color: inherit;
                padding: 0;
                background: none;
                font-size: 0.8rem;
            }
    
            .hljs-comment,
            .hljs-quote {
                color: #616161;
            }
    
            .hljs-variable,
            .hljs-template-variable,
            .hljs-attribute,
            .hljs-tag,
            .hljs-name,
            .hljs-regexp,
            .hljs-link,
            .hljs-name,
            .hljs-selector-id,
            .hljs-selector-class {
                color: #F98181;
            }
    
            .hljs-number,
            .hljs-meta,
            .hljs-built_in,
            .hljs-builtin-name,
            .hljs-literal,
            .hljs-type,
            .hljs-params {
                color: #FBBC88;
            }
    
            .hljs-string,
            .hljs-symbol,
            .hljs-bullet {
                color: #B9F18D;
            }
    
            .hljs-title,
            .hljs-section {
                color: #FAF594;
            }
    
            .hljs-keyword,
            .hljs-selector-tag {
                color: #70CFF8;
            }
    
            .hljs-emphasis {
                font-style: italic;
            }
    
            .hljs-strong {
                font-weight: 700;
            }
        } 
    

    The code should now be highlighted.