@shinyaz

rehype-pretty-code replaces language-mermaid className with data-language attribute

1 min read

I was adding Mermaid diagram rendering to an MDX blog. The plan was simple: override pre in mdx-components and check for className="language-mermaid". It didn't match anything.

Inspecting the Velite build output revealed rehype-pretty-code completely rewrites the structure:

{
  "before": "<pre><code class=\"language-mermaid\">graph TD...</code></pre>",
  "after": "<figure data-rehype-pretty-code-figure><pre data-language=\"mermaid\"><code data-language=\"mermaid\"><span data-line><span style=\"...\">graph TD</span></span>...</code></pre></figure>"
}

The className is gone, replaced by data-language. The text content is split into nested <span data-line> elements. The fix requires two steps:

// 1. Detect via data-language
function isMermaidBlock(props, child) {
  if (props["data-language"] === "mermaid") return true;
  if (child?.props?.className === "language-mermaid") return true;
  return false;
}
 
// 2. Recursively walk span tree to recover text
function extractTextFromChildren(children) {
  const parts = [];
  function walk(node) {
    if (typeof node === "string") { parts.push(node); return; }
    if (React.isValidElement(node)) walk(node.props.children);
    if (Array.isArray(node)) node.forEach(walk);
  }
  walk(children);
  return parts.join("");
}

When overriding MDX components, always inspect the actual post-build HTML structure in .velite/ output rather than assuming standard Markdown AST conventions. Rehype plugins can transform things in surprising ways.

Share this post

Shinya Tahara

Shinya Tahara

Solutions Architect @ AWS

I'm a Solutions Architect at AWS, providing technical guidance primarily to financial industry customers. I share learnings about cloud architecture and AI/ML on this site.The views and opinions expressed on this site are my own and do not represent the official positions of my employer.