Hooking onto Docusaurus' MDX Loader #10829
-
I'm building out a code labs style functionality into one of our docusaurus sites, with the goal of having a single MDX file broken up into multiple steps, which can then be piped into a component for further processing & layout. I've created a simple remark plugin that defines new remark direction called step import { visit } from 'unist-util-visit';
const plugin = () => {
const transformer = async (ast, vfile) => {
// Check and only parse MDX files within '/tutorials'
if (vfile.path.includes('/tutorials')) {
visit(ast, (node) => {
if (node.type === 'containerDirective') {
if (node.name !== 'step') {
return;
}
node.data = {
hName: 'StepComponent',
hProperties: {
className: 'codelabs-step'
}
};
node.children = node.children || [];
}
});
}
};
return transformer;
};
export default plugin; Example usage.. :::step
Other content & children go here
::: And this has been loaded via the remarkPlugins of the This is working when my plugin just wraps a some HTML elements around the markdown, by when I try to return a JSX/React component(like StepComponent above) and pass that component via the MDXComponents & MDXProvider.. ...
import Mermaid from '@theme/Mermaid';
import StepComponent from './StepComponent.js';
const MDXComponents = {
Head,
details: MDXDetails,
Details: MDXDetails,
[...]
mermaid: Mermaid,
table: MDXTable,
step: StepComponent // my component here
};
export default MDXComponents; This errors out with I don't believe this is an issue with how this component is passed to MDXComponents (as all those imports look good), but I'm missing some config that is allowing MDX to 'see' my component during the build. Perhaps I would need to be able to get my custom component added to the mdx-loader's processor.ts Any guidance on how I can make my new remark directive return a custom component would be great. Or if you see a problem with my approach, all input is welcome. Thanks 🙏 |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 2 replies
-
So your remark plugin essentially transforms: :::step
Other content & children go here
::: into <StepComponent>
Other content & children go here
</StepComponent> Note that it's possible for your remark plugin to automatically add the import to the MDX file. But your solution using our import React, {type ReactNode} from 'react';
import {MDXProvider} from '@mdx-js/react';
import MDXComponents from '@theme/MDXComponents';
import type {Props} from '@theme/MDXContent';
export default function MDXContent({children}: Props): ReactNode {
return <MDXProvider components={MDXComponents}>{children}</MDXProvider>;
} This likely doesn't work because you used Using In any case, before using directives, make sure you can use the JSX. The directive is only a "shortcut" to the JSX component you map it to. Also make sure to use an upper-case component name/mapping (like it's the case here https://docusaurus.io/docs/next/markdown-features/react#mdx-component-scope I could help you more if you provided a runnable repro I could fix. |
Beta Was this translation helpful? Give feedback.
So your remark plugin essentially transforms:
into
Note that it's possible for your remark plugin to automatically add the import to the MDX file. But your solution using our
MDXComponents
mapping should work, which under the hood is just using a regular MDXProvider: