MDX Integration
Ecopages supports MDX through three paths. Pick the integration that owns the JSX runtime for your MDX routes:
| Runtime | Plugin | When to use |
|---|---|---|
| React | reactPlugin({ mdx: { enabled: true } }) | React apps with routing, hydration, and HMR |
| Ecopages JSX | ecopagesJsxPlugin({ mdx: { enabled: true } }) | Ecopages-owned .tsx routes with optional Radiant |
| Third-party (KitaJS, etc.) | Standalone mdxPlugin() | Server-rendered MDX on a non-owned JSX runtime |
This page documents the standalone @ecopages/mdx plugin. Use it when MDX should compile against a third-party JSX runtime you install yourself.
Installation
@mdx-js/mdx is a peer dependency of @ecopages/mdx. Install the JSX runtime you pass to compilerOptions.jsxImportSource (the example above uses @kitajs/html).
Standalone MDX plugin
Add mdxPlugin to your Ecopages configuration with an explicit compilerOptions.jsxImportSource:
import { ConfigBuilder } from '@ecopages/core/config-builder';
import { mdxPlugin } from '@ecopages/mdx';
const appRoot = process.cwd();
const config = await new ConfigBuilder()
.setRootDir(appRoot)
.setBaseUrl(process.env.ECOPAGES_BASE_URL ?? 'http://localhost:3000')
.setIntegrations([
mdxPlugin({
compilerOptions: {
jsxImportSource: '@kitajs/html',
},
}),
])
.build();
export default config;JSX runtime rules
- Required:
compilerOptions.jsxImportSourceon standalonemdxPlugin(). - Rejected:
reactand@ecopages/jsx— usereactPluginorecopagesJsxPlugininstead. - Known values:
@kitajs/html, or any custom third-party runtime string.
Features
Layouts
Export a layout component from your MDX file to wrap page content:
import { BaseLayout } from '@/layouts/base-layout';
export const config = {
layout: BaseLayout,
};
# Hello World
This content will be wrapped by the BaseLayout component.Metadata
Export getMetadata for page title and description:
export const getMetadata = () => ({
title: 'My MDX Page',
description: 'This is a description for the MDX page.',
});
# Content
Page content goes here...Using Components
Import components directly in MDX. Top-level component imports are discovered automatically. Export a config object when you need a layout or explicit page scripts:
import { Card } from '@/components/card';
import { BaseLayout } from '@/layouts/base-layout';
export const config = {
layout: BaseLayout,
};
# Dashboard
<Card title="Analytics" value="100%" />Configuration
Pass standard MDX compile options through compilerOptions. jsxImportSource is required:
mdxPlugin({
extensions: ['.mdx', '.md'],
compilerOptions: {
jsxImportSource: '@kitajs/html',
remarkPlugins: [],
rehypePlugins: [],
recmaPlugins: [],
},
});MDX with React Router
For @ecopages/react with a client-side router, enable MDX on the React plugin:
import { reactPlugin } from '@ecopages/react';
import { ecoRouter } from '@ecopages/react-router';
reactPlugin({
router: ecoRouter(),
mdx: { enabled: true },
});See the React Integration for routing, hydration, and HMR details.
Mixing with Other Integrations
Standalone MDX works alongside other integrations when MDX routes stay on your chosen third-party JSX runtime.
Example: MDX on KitaJS with Lit for nested foreign subtrees:
import { ConfigBuilder } from '@ecopages/core/config-builder';
import { mdxPlugin } from '@ecopages/mdx';
import { litPlugin } from '@ecopages/lit';
const config = await new ConfigBuilder()
.setIntegrations([
mdxPlugin({
compilerOptions: {
jsxImportSource: '@kitajs/html',
},
}),
litPlugin(),
])
.build();Use reactPlugin({ mdx: { enabled: true } }) when MDX routes should compile and hydrate as React.