remark-unravel-mdx
v1.0.0
Published
**[remark][]** plugin to unwrap paragraph elements that only contain [MDX][] JSX elements and paragraphs inside MDX components.
Downloads
6,763
Readme
remark-unravel-mdx
remark plugin to unwrap paragraph elements that only contain MDX JSX elements and paragraphs inside MDX components.
Contents
- What is this?
- When should I use this?
- Install
- Use
- API
- Examples
- Syntax tree
- Compatibility
- Security
- Related
- Contribute
- License
What is this?
This package is a unified (remark) plugin that removes paragraph wrappers in two scenarios:
- Paragraphs containing only JSX elements: When a paragraph contains only MDX JSX elements (and whitespace), the paragraph wrapper is removed.
- Single paragraph inside MDX components: When MDX components have exactly one paragraph child, that paragraph is unwrapped to prevent styling conflicts. Components with multiple children preserve their paragraph structure for safety.
When should I use this?
This plugin is useful when you're using MDX and want to prevent unnecessary paragraph wrapping. This is particularly important when:
- Your JSX components are block-level elements that shouldn't be inside paragraphs
- You want cleaner HTML output without unnecessary
<p>wrapper elements - You're building a content pipeline where paragraph wrapping interferes with your component styling
- You want content inside JSX components to render without a paragraph wrapper for better styling control
Regular text content and mixed content paragraphs remain unchanged.
Install
This package is ESM only.
npm install remark-unravel-mdxyarn add remark-unravel-mdx<script type="module">
import {remarkUnravelMdx} from 'https://esm.sh/remark-unravel-mdx?bundle'
</script>Use
example.mdx:
This is a regular paragraph.
This paragraph has an <InlineComponent>inline component</InlineComponent> inside it.
<CustomComponent>
This content will be unwrapped from its paragraph.
</CustomComponent>example.ts:
import {readFileSync} from 'node:fs'
import {remark} from 'remark'
import remarkMdx from 'remark-mdx'
import {remarkUnravelMdx} from 'remark-unravel-mdx'
import remarkRehype from 'remark-rehype'
import {rehypeMdxElements} from "rehype-mdx-elements";
import rehypeStringify from 'rehype-stringify'
const file = readFileSync('example.mdx')
const result = await remark()
.use(remarkMdx)
.use(remarkUnravelMdx)
.use(remarkRehype, {
passThrough: ["mdxJsxFlowElement", "mdxJsxTextElement"],
})
.use(rehypeMdxElements)
.use(rehypeStringify)
.process(file)
console.log(String(result))
Running example.ts produces an HTML string with the following content:
<p>This is a regular paragraph.</p>
<CustomComponent>This component is on one line.</CustomComponent>
<CustomComponent>This component spans multiple lines</CustomComponent>If remarkUnravelMdx is not used it will produce the following content with paragraph wrappers:
<p>This is a regular paragraph.</p>
<p><CustomComponent>This component is on one line.</CustomComponent></p>
<CustomComponent><p>This component spans multiple lines</p></CustomComponent>API
remarkUnravelMdx()
Remove paragraph wrappers around MDX JSX elements and inside MDX components.
Returns
Transform (Transformer).
Syntax tree
This plugin modifies the mdast syntax tree by:
- Finding paragraph nodes that contain only MDX JSX text elements and whitespace
- Replacing those paragraph nodes with their children directly
- Finding single paragraphs that are the sole child of MDX JSX elements
- Unwrapping those single paragraphs by replacing them with their children
- Preserving the original position and structure of all elements
For example, this paragraph node:
{
type: 'paragraph',
children: [
{type: 'mdxJsxTextElement', name: 'MyComponent', children: []}
]
}Becomes:
{type: 'mdxJsxTextElement', name: 'MyComponent', children: []}Related
remark-mdx— adds support for MDX syntax parsingremark-parse— parses markdown to remark ASTremark-rehype— transform remark to rehype
