@conloca/mdx
Overview
@conloca/mdx provides MDX processing for both browser and server environments. In the browser, it powers the CMS block
editor with a full MDX editing experience. On the server, it compiles and evaluates MDX content for static site
generation.
Installation
bun add @conloca/mdx
Entry Points
@conloca/mdx (browser-safe)
Components and hooks for the CMS editor interface.
import { MDXEditor, useMDXEvaluation } from '@conloca/mdx';
| Export | Kind | Purpose |
|---|---|---|
MDXEditor | component | Full MDX editor with toolbar, ready to mount inside a page layout |
BaseMDXEditor | component | Lower-level primitive that accepts an image-dialog hook |
useMDXEvaluation | hook | Run pre-compiled MDX code into a React component at runtime |
MDXEditorMethods | type | Ref methods for programmatic editor control (from @mdxeditor/editor) |
@conloca/mdx/node (Node.js only)
Server-side MDX compilation and evaluation.
import { compileMDX, evaluateMDXToComponent, evaluateMDXBlocks } from '@conloca/mdx/node';
| Export | Purpose |
|---|---|
compileMDX(content) | Compile MDX string to JavaScript and extract frontmatter |
evaluateMDXToComponent(source) | Compile and evaluate MDX to a React component |
evaluateMDXBlocks(api, locale) | Fetch all blocks from a compatible API and evaluate their MDX |
Usage
Browser: MDX Editor
The MDXEditor component provides a rich MDX editing experience and is designed to be mounted inline inside your own
page layout. The CMS SPA uses it directly at /blocks/:id and /pages/:id (page-route editor pattern).
import { MDXEditor } from '@conloca/mdx';
import { useState } from 'react';
function BlockEditor({ initialContent, onSave }) {
const [content, setContent] = useState(initialContent);
return (
<div className="h-screen flex flex-col">
<header>{/* your toolbar / save button */}</header>
<div className="flex-1 overflow-hidden">
<MDXEditor value={content} onChange={setContent} onSave={onSave} autoFocus />
</div>
</div>
);
}
MDXEditor Props:
| Prop | Type | Required | Description |
|---|---|---|---|
value | string | Yes | Initial MDX content for the editor |
onChange | (value: string, initialNormalize?: boolean) => void | Yes | Called whenever the editor content changes |
onSave | (value: string) => void | No | Cmd/Ctrl+S handler |
readOnly | boolean | No | Disable editing |
className | string | No | Forwarded to the MDXEditor root; pass "dark-theme" for the library’s dark palette |
placeholder | ReactNode | No | Empty-state placeholder |
autoFocus | boolean | No | Focus the editor on mount |
Browser: MDX Rendering
Use useMDXEvaluation to render MDX content as React components in the browser:
import { useMDXEvaluation } from '@conloca/mdx';
function MDXPreview({ compiledCode }) {
const { Component, error, isLoading, retry } = useMDXEvaluation({ compiledCode });
if (isLoading) return <p>Loading...</p>;
if (error)
return (
<p>
Error rendering MDX: {error.message} <button onClick={retry}>Retry</button>
</p>
);
if (!Component) return null;
return <Component />;
}
Server: Compile MDX
import { compileMDX } from '@conloca/mdx/node';
const result = await compileMDX('# Hello World\n\nSome **bold** text.');
console.log(result.code); // Compiled JavaScript
console.log(result.metadata); // Extracted frontmatter
Server: Evaluate MDX to Component
import { evaluateMDXToComponent } from '@conloca/mdx/node';
const { Component, error } = await evaluateMDXToComponent('# Hello World');
if (Component) {
// Render the component in your framework
}
Server: Evaluate All Blocks
import { evaluateMDXBlocks } from '@conloca/mdx/node';
import { createContentAPI } from '@conloca/content-api/node';
const api = await createContentAPI({ contentRoot: './content' });
const blocks = await evaluateMDXBlocks(api, 'en');
// blocks is an Array of structured success/error results
for (const block of blocks) {
console.log(`Block: ${block.id} (${block.title})`);
if (!block.ok) {
console.error(block.error.message);
continue;
}
// Render block.Component in your React app
}
MDX Features
The MDX compiler supports:
- Standard Markdown syntax (headings, lists, bold, italic, links, images)
- GitHub Flavored Markdown (tables, strikethrough, task lists) via
remark-gfm - Frontmatter via
remark-frontmatterandremark-mdx-frontmatter - JSX components within MDX content
Dependencies
| Library | Purpose |
|---|---|
@mdx-js/mdx | Core MDX compiler |
@mdx-js/react | React runtime for MDX |
@mdxeditor/editor | Rich MDX editor component |
remark-gfm | GitHub Flavored Markdown support |
remark-frontmatter | YAML frontmatter parsing |
remark-mdx-frontmatter | Frontmatter in MDX exports |