Next.js & React Integration
The @toaq-oss/omni-mdx package is the React/Next.js visual rendering engine of the TOAQ-oss MDX ecosystem. It consumes the ultra-fast Abstract Syntax Tree (AST) generated by our Rust core and transforms it into interactive, secure, and highly customizable React components.
Why This Exists
Most MDX pipelines run at the JS level and require client-side hydration for math, syntax highlighting, and custom components. This traditional approach causes several issues:
- A large JS bundle sent to every visitor.
- Math rendered on the client (flash of unstyled content).
- Custom components that can’t be pure Server Components.
@toaq-oss/omni-mdx solves this by moving the parse step into Rust and the render step into React Server Components. The result is zero JS for content — everything is HTML by the time it reaches the browser.
Server Components (Recommended)
The most efficient way to use Omni-MDX is within Next.js App Router Server Components.
Because parseMdx is async and runs on the server, it works naturally with generateStaticParams for Static Site Generation (SSG). At next build, Next.js calls parseMdx once per article and pre-renders everything to static HTML. The Rust parser never runs in the browser.
Live Editor (Client-Side)
For live MDX previews where the content changes directly in the browser, you can use the client renderer:
The ast prop should be computed server-side and passed down, or computed client-side by calling a Route Handler that runs parseMdx.
Component Registry
You can map JSX tags found in your MDX directly to your own React components. Register components by name — the key matches the JSX tag in the MDX source:
Server Components in the registry are rendered on the server with zero client JS. Client Components are hydrated normally.
Error Handling
Parse Errors
When generating the AST on the server, you can catch syntax issues using the custom MDXParseError class:
Component Boundaries
In MDXClientRenderer, every custom component is automatically wrapped in MDXErrorBoundary. If a component throws, the error is isolated — the rest of the document continues to render.
Math & KaTeX
Math is handled entirely by the Rust parser — no remark-math or rehype-katex needed.
The parser transforms expressions into HTML data attributes:
- Inline (
$E = mc^2$) outputs<span class="math math-inline" data-math="…">. - Display (
$$…$$) outputs<div class="math math-display" data-math="…">.
KaTeX hydrates the data-math attributes on the client via MDXClientRenderer, or you can use any KaTeX auto-render script in your layout. Just remember to import the stylesheet:
Runtime Detection
The package auto-detects the environment and loads the appropriate backend without any configuration required.
- Native .node execution: Supported on Node.js 18+ and Next.js (RSC).
- WASM Fallback: Available across all environments, including Edge runtimes and the Browser.