
Security News
Another Round of TEA Protocol Spam Floods npm, But It’s Not a Worm
Recent coverage mislabels the latest TEA protocol spam as a worm. Here’s what’s actually happening.
@diplodoc/mdx-extension
Advanced tools
[](https://www.npmjs.com/package/@diplodoc/mdx-extension) [](https://opensource.org/licenses/MIT)
MDX extension for Diplodoc's markdown transformer that allows embedding MDX/JSX components within markdown content.
npm install @diplodoc/mdx-extension
# or
yarn add @diplodoc/mdx-extension
<MDX>...</MDX> tags<>...</><Component />withPortalidMdxComponentLoaderFirst, add the mdxPlugin() to your Diplodoc transform plugins:
import transform from '@diplodoc/transform';
import DefaultPlugins from '@diplodoc/transform/lib/plugins';
import {mdxPlugin} from '@diplodoc/mdx-extension';
const result = transform(markdownContent, {
plugins: [...DefaultPlugins, mdxPlugin()],
});
To enable security validation of MDX input and prevent execution of potentially unsafe code:
import {mdxPlugin, validateMdx} from '@diplodoc/mdx-extension';
const result = transform(markdownContent, {
plugins: [
...DefaultPlugins,
mdxPlugin({
compileOptions: {
recmaPlugins: [validateMdx],
},
}),
],
});
This will:
import React, {Fragment, useMemo, useRef} from 'react';
import transform from '@diplodoc/transform';
import DefaultPlugins from '@diplodoc/transform/lib/plugins';
import {mdxPlugin, useMdx, isWithMdxArtifacts, validateMdx} from '@diplodoc/mdx-extension';
const Components = {
CustomComponent: (props) => <div {...props}>Custom</div>,
};
const CONTENT = `
# Markdown Content
<CustomComponent style={{color: 'red'}} />
<MDX>
<div>This will be rendered as MDX</div>
</MDX>
`;
function App() {
const ref = useRef(null);
const {html, mdxArtifacts} = useMemo(() => {
const {result} = transform(CONTENT, {
plugins: [
...DefaultPlugins,
mdxPlugin({
compileOptions: {
recmaPlugins: [validateMdx],
},
}),
],
});
isWithMdxArtifacts(result);
return result;
}, []);
const portals = useMdx({
refCtr: ref,
html,
components: Components,
mdxArtifacts,
});
return (
<Fragment>
<div ref={ref}></div>
{portals}
</Fragment>
);
}
import React from 'react';
import transform from '@diplodoc/transform';
import DefaultPlugins from '@diplodoc/transform/lib/plugins';
import {mdxPlugin, useMdxSsr, getSsrRenderer, validateMdx} from '@diplodoc/mdx-extension';
const Components = {
ServerComponent: (props) => <strong {...props}>Server Rendered</strong>,
};
const CONTENT = `
# Server Rendered Content
<ServerComponent />
`;
export async function getServerSideProps() {
const render = await getSsrRenderer({
components: Components,
compileOptions: {
recmaPlugins: [validateMdx],
},
});
const {result} = transform(CONTENT, {
plugins: [...DefaultPlugins, mdxPlugin({render})],
});
isWithMdxArtifacts(result);
const {html, mdxArtifacts} = result;
return {props: {html, mdxArtifacts}};
}
function ServerPage({html, mdxArtifacts}) {
const ref = useRef(null);
const portals = useMdxSsr({
refCtr: ref,
components: Components,
mdxArtifacts,
html,
});
const innerHtml = useMemo(() => {
return {__html: html};
}, [html]);
return (
<Fragment>
<div ref={ref} dangerouslySetInnerHTML={innerHtml}></div>
{portals}
</Fragment>
);
}
The collect plugin provides functionality to process and transform MDX content while collecting artifacts. It comes in both synchronous and asynchronous versions.
import {getMdxCollectPlugin} from '@diplodoc/mdx-extension';
const plugin = getMdxCollectPlugin({
tagNames: ['CustomComponent'], // Optional filter for specific tags
pureComponents: PURE_COMPONENTS,
compileOptions: {
// MDX compilation options
},
});
const transformedContent = plugin(originalContent);
import {getAsyncMdxCollectPlugin} from '@diplodoc/mdx-extension';
const asyncPlugin = getAsyncMdxCollectPlugin({
tagNames: ['AsyncComponent'], // Optional filter for specific tags
pureComponents: PURE_COMPONENTS,
compileOptions: {
// MDX compilation options
},
});
const transformedContent = await asyncPlugin(originalContent);
mdxPlugin(options?: { render?: MDXRenderer })The main plugin function that enables MDX processing.
render: Optional renderer function, for SSR use getSsrRenderertagNames?: string[] - Optional array of tag names to filter which components will be processeduseMdx(options: UseMdxProps): React.FragmentReact hook for client-side MDX processing.
refCtr: Ref to the container elementhtml: HTML string from Diplodoc transformcomponents: Object of React components to usemdxArtifacts: MDX artifacts from transformpureComponents?: Optional object of components that shouldn't hydrate (MDXComponents)contextList?: Array of React contexts to provide to MDX componentsuseMdxSsr(options: UseMdxSsrProps): React.FragmentReact hook for SSR-processed MDX content.
refCtr: Ref to the container elementhtml: HTML string from Diplodoc transformcomponents: Object of React components to usemdxArtifacts: MDX artifacts from transformpureComponents?: Optional object of components that shouldn't hydrate (MDXComponents)contextList?: Array of React contexts to provide to MDX componentsgetRenderer(options: GetRenderProps)Creates an renderer function for client-side processing.
compileOptions?: MDX compilation options (see MDX documentation)getSsrRenderer(options: GetSsrRendererProps)Creates an SSR renderer function for server-side processing.
components: Object of React components to usepureComponents?: Optional object of components that shouldn't hydrate (MDXComponents)compileOptions?: MDX compilation options (see MDX documentation)contextList?: Array of React contexts to provide to MDX components. Use { ctx, initValue } format to pass initial values for SSRgetAsyncSsrRenderer(options: GetAsyncSsrRendererProps)Creates an asynchronous SSR renderer that supports withInitialProps.
components: Object of React components to usepureComponents?: Optional object of components that shouldn't hydrate (MDXComponents)compileOptions?: MDX compilation options (see MDX documentation)contextList?: Array of React contexts to provide to MDX components. Use { ctx, initValue } format to pass initial values for SSRgetMdxCollectPlugin(options: Options)Creates a synchronous collect plugin for processing MDX content.
tagNames?: string[] - Optional array of tag names to filter processingpureComponents?: Components that should skip client-side hydrationcompileOptions?: MDX compilation optionsgetAsyncMdxCollectPlugin(options: AsyncOptions)Creates an asynchronous collect plugin that supports components with initial props.
tagNames?: string[] - Optional array of tag names to filter processingpureComponents?: Components that should skip client-side hydrationcompileOptions?: MDX compilation optionsMdxStateCtx: Context<MdxStateCtxValue>Provides access to the current MDX state:
const state = useContext(MdxStateCtx);
MdxSetStateCtx: Context<MdxSetStateCtxValue>Provides state setter function (only available during SSR):
const setState = useContext(MdxSetStateCtx);
// Usage in SSR:
setState?.({key: value});
withInitialProps: WithInitialPropsWraps a component to enable initial props fetching during SSR.
Parameters:
component: React component to wrapgetInitProps: Function that receives props and MDX state, returns props (sync or async)withPortal: WithPortalPropsWraps a component to render it through React.createPortal, allowing for more flexible mounting.
Parameters:
component: React component to wrapfallback: Optional fallback component to show before portal is mountedUsage:
export const COMPONENTS = {
Tabs: withPortal(TabsLocal, () => <Skeleton />),
};
When using withPortal, the component will:
<MDX>
<MyComponent prop="value" />
</MDX>
<>
<div>Fragment content</div>
</>
<Button onClick={() => console.log('click')}>
Click me
</Button>
The library provides two context providers for managing state during Server-Side Rendering (SSR):
MdxSetStateCtx - A context that provides a function to update the MDX state. This function is only available during SSR (null on client-side). If you set a component's state using this context, it will be:
data-mdx-state attribute during SSRMdxStateCtx when the component rendersMdxStateCtx - A context that provides access to the current MDX state value
withInitialProps - A higher-order component that enables asynchronous data fetching for SSR:
getAsyncSsrRenderer, the getInitialProps function will be calledgetAsyncSsrRenderer - An asynchronous version of getSsrRenderer that:
withInitialPropsExample usage:
const getInitialProps: MDXGetInitialProps<CounterProps> = (props, mdxState) => {
mdxState.initialValue = 10; // Set initial state
return props;
};
export const SSR_COMPONENTS = {
...COMPONENTS,
Counter: withInitialProps(Counter, getInitialProps),
};
The library supports pure components that:
pureComponents option in:
useMdxuseMdxSsrgetSsrRenderergetAsyncSsrRendererExample:
export const PURE_COMPONENTS = {
KatexFormula, // Will render once on server and not hydrate
Label, // on client
CompatTable,
Alert,
};
The useMdx and useMdxSsr hooks now support an optional idMdxComponentLoader parameter that enables asynchronous loading of MDX components:
interface PageProps {
html: string;
mdxArtifacts?: MdxArtifacts;
withLoader?: boolean;
}
const Page: FC<PageProps> = ({html, mdxArtifacts}) => {
const [isSuccess, setSuccess] = React.useState(false);
const [data, setData] = React.useState<IdMdxComponentLoader['data']>(undefined);
useMdxSsr({
// ...other options
idMdxComponentLoader: {isSuccess, data},
});
useEffect(() => {
(async () => {
const idMdxComponent: Record<string, React.ComponentType<MDXProps>> = {};
for (const [artifactId, code] of Object.entries(mdxArtifacts?.idMdx ?? {})) {
const fn = await asyncExecuteCode(code);
idMdxComponent[artifactId] = fn(runtime).default;
}
setData(idMdxComponent);
setSuccess(true);
})();
}, [mdxArtifacts]);
// ...rest of the component
};
All renderer functions (getSsrRenderer, getAsyncSsrRenderer, getRenderer) now accept optional MDX compilation options:
const renderer = await getAsyncSsrRenderer({
components: SSR_COMPONENTS,
pureComponents: PURE_COMPONENTS,
compileOptions: {
// MDX compilation options here
},
});
This allows for fine-grained control over the MDX compilation process while maintaining the library's core functionality.
MIT
FAQs
[](https://www.npmjs.com/package/@diplodoc/mdx-extension) [](https://opensource.org/licenses/MIT)
We found that @diplodoc/mdx-extension demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 7 open source maintainers collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Recent coverage mislabels the latest TEA protocol spam as a worm. Here’s what’s actually happening.

Security News
PyPI adds Trusted Publishing support for GitLab Self-Managed as adoption reaches 25% of uploads

Research
/Security News
A malicious Chrome extension posing as an Ethereum wallet steals seed phrases by encoding them into Sui transactions, enabling full wallet takeover.