MUI Docs Infra

Transform HTML Code Precomputed

A rehype plugin that transforms <pre> elements containing <code> blocks into precomputed data for the CodeHighlighter component. This plugin extracts source code from HTML, processes it through syntax highlighting and transformations, then stores the results for efficient client-side rendering.

Overview

This plugin is typically used in the second stage of a markdown-to-HTML processing pipeline, after transformMarkdownCodeVariants has converted markdown code blocks into HTML structures.

Key Features

  • Multiple code variants: Process multiple languages or versions within a single code block
  • Automatic language detection: Determines file types from class="language-*" attributes
  • Custom variant names: Supports data-variant attribute for explicit naming
  • Custom filenames: Supports data-filename attribute for specific file extensions
  • Opt-in transformations: Code blocks are only transformed when marked with data-transform="true"
  • Built-in transformations: Includes TypeScript-to-JavaScript conversion for marked blocks
  • Syntax highlighting: Pre-processes code for faster client rendering
  • Error handling: Gracefully handles processing errors

Installation & Usage

import { unified } from 'unified';
import rehypeParse from 'rehype-parse';
import transformHtmlCodePrecomputed from '@mui/internal-docs-infra/pipeline/transformHtmlCodePrecomputed';

const processor = unified()
  .use(rehypeParse)
  .use(transformHtmlCodePrecomputed) // No configuration needed
  .use(rehypeStringify);

With Next.js and MDX

// next.config.js
const withMDX = require('@next/mdx')({
  options: {
    remarkPlugins: [transformMarkdownCodeVariants],
    rehypePlugins: [transformHtmlCodePrecomputed],
  },
});

module.exports = withMDX({
  // your Next.js config
});

Input Examples

Single Code Block

<pre><code class="language-typescript">
const greeting: string = "Hello, world!";
console.log(greeting);
</code></pre>

Multiple Code Variants (Different Languages)

<pre>
  <code class="language-javascript">console.log("Hello, world!");</code>
  <code class="language-typescript">console.log("Hello, world!" as string);</code>
</pre>

Custom Variant Names

<pre>
  <code class="language-javascript" data-variant="Client">console.log("Running on client");</code>
  <code class="language-javascript" data-variant="Server">console.log("Running on server");</code>
</pre>

Custom Filenames

<pre><code class="language-javascript" data-filename="app.jsx">
const App = () => <div>Hello React!</div>;
export default App;
</code></pre>

Code Block Transformations

By default, code blocks are processed for syntax highlighting only. To enable transformations (like TypeScript-to-JavaScript conversion), explicitly mark the code block:

<pre><code class="language-typescript" data-transform="true">
const greeting: string = "Hello, world!";
console.log(greeting);
</code></pre>

This will generate both the original TypeScript and the transformed JavaScript versions.

Output

After processing, the plugin:

  1. Replaces content with a placeholder message
  2. Stores processed data in data-precompute attribute as JSON
  3. Passes through metadata like data-name and data-slug attributes
  4. Serializes custom props in data-content-props attribute as JSON
<pre
  data-precompute='{"Default":{"fileName":"index.ts","source":"...","transforms":{...}}}'
  data-name="My Demo"
  data-slug="my-demo"
  data-content-props='{"title":"Example Code"}'
>
  Error: expected pre tag to be handled by CodeHighlighter
</pre>

Data Attributes

The following data-* attributes are supported on code elements:

Reserved Attributes (handled internally)

AttributePurpose
data-filenameSets the filename for the code variant
data-variantSets the variant name
data-transformEnables TypeScript→JavaScript transformation when "true"
data-nameDemo name, passed through to the output <pre> element
data-slugURL slug for the demo, passed through to the output <pre> element

Custom Attributes (passed to content component)

Any other data-* attributes on the code element are serialized as JSON in the data-content-props attribute on the output <pre> element. These can be used by your content component for custom features.

Example:

<pre><code class="language-typescript" data-title="Example">
const x = 1;
const y = 2;
</code></pre>

The output <pre> element will include:

<pre data-content-props='{"title":"Example"}' ...></pre>

Variant Naming

ScenarioVariant Names
Single code block"Default"
Different languages"Js", "Ts", "Html", etc.
Same language"Variant 1", "Variant 2", etc.
Custom data-variantUses the specified name

Supported Languages

class="language-*"ExtensionNotes
javascript.jsAlso accepts js (normalized)
typescript.tsAlso accepts ts; includes TS→JS transform when data-transform="true"
tsx.tsxReact TypeScript
jsx.jsxReact JavaScript
json.json
html.html
css.css
shell.shAlso accepts bash, sh
yaml.yamlAlso accepts yml
markdown.mdAlso accepts md
Others.txtFallback

Integration with transformMarkdownCodeVariants

These plugins work together in a processing pipeline:

  1. transformMarkdownCodeVariants (remark): Converts markdown code blocks with variants into HTML
  2. transformHtmlCode (rehype): Processes the HTML and precomputes data for rendering

Complete Example

Markdown Input:

npm

```bash variant-group=install
npm install package
```

pnpm

```bash variant-group=install
pnpm install package
```

After transformMarkdownCodeVariants:

<pre>
  <code class="language-shell" data-variant="npm">npm install package</code>
  <code class="language-shell" data-variant="pnpm">pnpm install package</code>
</pre>

After transformHtmlCode:

<pre data-precompute='{"npm":{"fileName":"index.sh","source":"npm install package"...}}'>
  Error: expected pre tag to be handled by CodeHighlighter
</pre>
  • Processes code blocks in parallel across the document
  • Optimized text extraction with single-pass traversal