Email

Code Editor in React

A simple React code highlighter

Adding Syntax Highlighting to Code Blocks in React

When writing a blog that includes code snippets, it’s important to make them easy to read. One way to do this is by adding syntax highlighting, which adds colours and styles to different parts of the code, just like you see in a code editor.

In this post, we’ll walk through a React component that takes in a piece of code and displays it with syntax highlighting.

Install Shiki to your frontend

npm i shiki

Add the following template to your project, where codeContent is your javascript/typescript, i.e console.log('hello world')

import { type JSX } from "react"

import { codeToHtml } from "shiki"

const CodeBlock = async (
  codeContent: string,
  lang: string = "typescript"
): Promise<JSX.Element> => {

  const codeHTML = await codeToHtml(codeContent, {
    lang,
    theme: "github-dark-dimmed",
  })
  return (
    <section className="sb-code">
      <div className="container">
        <div
          className="shadow-[0px_3px_3px_0px_rgba(0,0,0,0.75)] overflow-hidden rounded-lg"
          dangerouslySetInnerHTML={{ __html: codeHTML }}
        />
      </div>
    </section>
  )
}

export default CodeBlock

This is how it is used

import Code from 'wherever/your/component/is/placed'
<Code code="console.log('hello world')" lang="typescript" />

What is Happening Under the Hood in CodeBlock?

Imports & Type Definitions

  • Imports JSX from React → Helps define that this component returns JSX elements.

  • Imports codeToHtml from shiki → Converts plain code into syntax-highlighted HTML.

Setting Up the Component

  • Declares CodeBlock as an async function → Because codeToHtml needs to fetch and process themes before returning the highlighted code.

  • Takes two arguments:

    • codeContent: any → The actual code snippet.

    • lang: string = "typescript" → The programming language (defaults to "typescript").

  • Returns a Promise<JSX.Element> → Since this is an asynchronous function, it resolves to a JSX element.

Generating Syntax-Highlighted HTML

  • Calls codeToHtml(codeContent, {...})

    • Passes the code snippet.

    • Specifies the programming language.

    • Uses the "github-dark-dimmed" theme.

  • await ensures the function waits for shiki to process the code before moving on.

Rendering the Code Block

  • Wraps the content inside a <section> (className="sb-code") to structure it.

  • Uses a <div className="container"> to apply consistent styling.

  • Inserts the processed HTML inside another <div> using dangerouslySetInnerHTML

    • Why dangerouslySetInnerHTML? → shiki generates pre-formatted HTML with <span> elements for colours, so we need to inject it directly.

  • Applies Tailwind CSS styles for better UI:

    • shadow-[0px_3px_3px_0px_rgba(0,0,0,0.75)] → Adds a subtle shadow.

    • overflow-hidden → Ensures content stays inside the box.

    • rounded-lg → Gives the block rounded corners.

Exporting the Component

  • Exports CodeBlock as the default export, making it reusable in other parts of the application.

Get in touch

I am always free to discuss new projects, opportunities or any assistance you may require.

Responses usually take less than 24 hours.