Is it possible to define custom MDX components using a data-attribute of the HTML element?
I'm working on a Next.js blog using contentlayer for MDX and Rehype Pretty Code for syntax highlighting code blocks. Below is the HTML output structure from Rehype Pretty code. I would like to create a custom MDX component for the below HTML, but the root elemen is a <div>
. So is it possible to target a div element using its data attribute - in this case div[data-rehype-pretty-code-fragment]
to create a custom MDX component?
<div data-rehype-pretty-code-fragment>
<div data-rehype-pretty-code-title="" data-language="js">sample.js</div>
<pre data-language="js">
<code data-line-numbers data-line-numbers-max-digits="2">
</span data-line="">
</span style="color:#C678DD">const</span>
<!-- more span elements ... -->
</code>
</pre>
<div data-rehype-pretty-code-caption>this is a sample caption</div>
</div>
above code block is shortened for brevity
Custom MDX Components:
is it possible to do this?
export const components: MDXComponents = {
// Add a custom component.
MyComponent: () => <div>Hello World!</div>,
div[data-rehype-pretty-code-fragment]: (props) => <CodeBlock {...props} />, // is this possible?
};
My Requirement
What I'm trying to do is to add additional DOM elements & classes to the code-block output like below classes codeBlockRoot
, customContent
& moreCustomContent
using a Custom JSX component and add styles to the entire code-block. Right now I'm having to use div[data-rehype-pretty-code-fragment]
to add styles to the code block:
<div class="codeBlockRoot" data-rehype-pretty-code-fragment>
<div class="customContent">this is custom HTML</div>
<div data-rehype-pretty-code-title="" data-language="js">
sample.js
<div class="moreCustomContent">more custom content</div>
</div>
<pre data-language="js">
<code data-line-numbers data-line-numbers-max-digits="2">
</span data-line="">
</span style="color:#C678DD">const</span>
<!-- more span elements ... -->
</code>
</pre>
<div data-rehype-pretty-code-caption>this is a sample caption</div>
</div>