Used

How toAdd syntax highlight to Markdoc using Prism.js

If you're using Markdoc like me, you may want to add syntax highlight, this is how I added it on my blog

First install the Prism.js package.

npm add prismjs
npm add -D @types/prismjs

Now, let create a component called Fence that will receive any code block and call Prism.

import Prism from "prismjs";

// Load the grammars you want to support
import "prismjs/components/prism-cshtml";
import "prismjs/components/prism-css";
import "prismjs/components/prism-javascript";
import "prismjs/components/prism-json";
import "prismjs/components/prism-jsx";
import "prismjs/components/prism-typescript";

type FenceProps = {
  children: string;
  language: string;
};

export function Fence({ children, language }: FenceProps) {
  let content = Prism.highlight(children, Prism.languages[language], language);

  return (
    <pre
      className={`language-${language}`}
      dangerouslySetInnerHTML={{ __html: content }}
    />
  );
}

export const fence = {
  render: "Fence",
  attributes: { language: { type: String } }
};

Now, go to where you call the Markdoc.transform function and pass your fence object.

import { parse, transform } from "@markdoc/markdoc";

// Here import your `fence` object
import { fence } from "~/components/fence";

export function parse(content: string) {
  return transform(parse(content), { nodes: { fence } })
}

And then use the Fence component where you render the React components.

import type { RenderableTreeNodes } from "@markdoc/markdoc";

import { renderers } from "@markdoc/markdoc";
import * as React from "react";

// Here import your component
import { Fence } from "~/components/fence";

type Props = { content: RenderableTreeNodes };

export function MarkdownView({ content }: Props) {
  return <>{renderers.react(content, React, { components: { Fence } })}</>;
}

And that's it.