Skip to content

@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';
ExportKindPurpose
MDXEditorcomponentFull MDX editor with toolbar, ready to mount inside a page layout
BaseMDXEditorcomponentLower-level primitive that accepts an image-dialog hook
useMDXEvaluationhookRun pre-compiled MDX code into a React component at runtime
MDXEditorMethodstypeRef 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';
ExportPurpose
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:

PropTypeRequiredDescription
valuestringYesInitial MDX content for the editor
onChange(value: string, initialNormalize?: boolean) => voidYesCalled whenever the editor content changes
onSave(value: string) => voidNoCmd/Ctrl+S handler
readOnlybooleanNoDisable editing
classNamestringNoForwarded to the MDXEditor root; pass "dark-theme" for the library’s dark palette
placeholderReactNodeNoEmpty-state placeholder
autoFocusbooleanNoFocus 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-frontmatter and remark-mdx-frontmatter
  • JSX components within MDX content

Dependencies

LibraryPurpose
@mdx-js/mdxCore MDX compiler
@mdx-js/reactReact runtime for MDX
@mdxeditor/editorRich MDX editor component
remark-gfmGitHub Flavored Markdown support
remark-frontmatterYAML frontmatter parsing
remark-mdx-frontmatterFrontmatter in MDX exports