Ecopages0.2.0-rc.4

MDX Integration

Ecopages supports MDX through three paths. Pick the integration that owns the JSX runtime for your MDX routes:

RuntimePluginWhen to use
ReactreactPlugin({ mdx: { enabled: true } })React apps with routing, hydration, and HMR
Ecopages JSXecopagesJsxPlugin({ 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

npm install @ecopages/mdx @mdx-js/mdx @kitajs/html

@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.jsxImportSource on standalone mdxPlugin().
  • Rejected: react and @ecopages/jsx — use reactPlugin or ecopagesJsxPlugin instead.
  • 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.