Framework Integration
Integrate notebook-mdx with popular documentation frameworks
Framework Integration
Learn how to integrate notebook-mdx with popular documentation frameworks. Get your Jupyter notebooks rendering beautifully in your documentation site.
🚀 General Setup
Installation
npm install notebook-mdxBasic Configuration
notebook-mdx requires two main components:
- Server-side: Remark plugin for processing notebook directives
- Client-side: React components for rendering notebooks
// Import the server plugin (includes remark-directive automatically)
import { remarkNotebook } from 'notebook-mdx/server';
// Import client components (one spread, all components included)
import { notebookComponents } from 'notebook-mdx/client';Usage in MDX
Once configured, you can embed notebooks using the directive syntax:
# My Tutorial
Basic notebook embedding:
:::notebook{file="./examples/basic.ipynb"}
:::
Show specific cells:
:::notebook{file="./examples/analysis.ipynb" cells="1-5"}
:::
Hide code, show only output:
:::notebook{file="./examples/visualization.ipynb" hideCode}
:::
With custom description:
:::notebook{file="./examples/demo.ipynb" showCellNumbers}
This notebook demonstrates data analysis techniques.
:::Configuration Options
// Custom base directory for notebooks
[remarkNotebook, {
baseDir: './content/notebooks',
}]
// Custom component name
[remarkNotebook, {
componentName: 'CustomNotebookRenderer',
}]Development Experience
notebook-mdx strives to provide a good development experience with several key benefits:
🔄 Development Workflow
Current state: Changes to .ipynb files don't automatically trigger hot module reload. Here's the current workflow:
- Edit your notebook in Jupyter/VSCode
- Trigger refresh by either:
- Resave the MDX file that contains the notebook directive
- Make a small edit to the MDX file and save
- Restart the dev server if the above doesn't work
🚧 Hot Module Reload (Coming Soon)
Full HMR support for notebooks is a priority on our roadmap! Soon you'll be able to:
- Edit notebooks in Jupyter/VSCode → See changes immediately in your docs
- Modify notebook cells → Updates appear instantly
- No workarounds needed → True hot reload experience
⚡ Fast Rendering
- Build-time processing - Notebooks are parsed during build for optimal runtime performance
- Optimized re-renders - Only changed cells update, not the entire notebook
- Zero hydration issues - Components render consistently between server and client
🛠️ Developer-Friendly
- TypeScript support - Full type safety and IntelliSense
- Clear error messages - Helpful debugging information when notebooks fail to load
- Component inspection - Works seamlessly with React DevTools
📚 Fumadocs
Status: ✅ Fully Supported
Fumadocs is a modern documentation framework built on Next.js.
Configuration
1. Update your source configuration
// source.config.ts
import { remarkNotebook } from 'notebook-mdx/server';
import { defineConfig, defineDocs } from 'fumadocs-mdx/config';
export const { docs, meta } = defineDocs({
dir: 'content/docs',
});
export default defineConfig({
mdxOptions: {
remarkPlugins: [
remarkNotebook, // Handles everything — no separate remark-directive needed
],
},
});2. Update MDX components
// mdx-components.tsx
import defaultMdxComponents from "fumadocs-ui/mdx";
import type { MDXComponents } from "mdx/types";
import { notebookComponents } from "notebook-mdx/client";
export function getMDXComponents(components?: MDXComponents): MDXComponents {
return {
...defaultMdxComponents,
...components,
...notebookComponents,
} as MDXComponents;
}Advanced Configuration
Custom Base Directory
// source.config.ts
export default defineConfig({
mdxOptions: {
remarkPlugins: [
[remarkNotebook, {
baseDir: './content/notebooks',
}],
],
},
});Custom Component Name
// source.config.ts
export default defineConfig({
mdxOptions: {
remarkPlugins: [
[remarkNotebook, {
componentName: 'CustomNotebookRenderer',
}],
],
},
});Project Structure
my-fumadocs-site/
├── app/
│ ├── layout.tsx
│ └── docs/
├── content/
│ ├── docs/
│ │ ├── index.mdx
│ │ ├── tutorial.mdx
│ │ └── examples/
│ │ ├── basic.ipynb # Notebooks alongside MDX
│ │ └── advanced.ipynb
│ └── notebooks/ # Or separate notebook directory
│ ├── data-analysis.ipynb
│ └── visualization.ipynb
├── source.config.ts
└── package.jsonBest Practices for Fumadocs
-
Organize notebooks alongside content:
content/docs/ ├── tutorial/ │ ├── index.mdx │ ├── basics.ipynb │ └── advanced.ipynb -
Use descriptive file names:
:::notebook{file="./data-analysis-pandas.ipynb"} ::: -
Leverage Fumadocs features:
<Callout type="info"> The following notebook demonstrates the core concepts: :::notebook{file="./core-concepts.ipynb" cells="1-3"} ::: </Callout>
📚 Next.js with MDX
Status: ✅ Fully Supported
Installation
npm install notebook-mdx @next/mdxConfiguration
// next.config.mjs
import { remarkNotebook } from 'notebook-mdx/server';
import createMDX from '@next/mdx';
const withMDX = createMDX({
options: {
remarkPlugins: [
remarkNotebook,
],
},
});
/** @type {import('next').NextConfig} */
const nextConfig = {
pageExtensions: ['js', 'jsx', 'ts', 'tsx', 'md', 'mdx'],
};
export default withMDX(nextConfig);mdx-components.tsx
import type { MDXComponents } from 'mdx/types';
import { notebookComponents } from 'notebook-mdx/client';
export function useMDXComponents(components: MDXComponents): MDXComponents {
return {
...components,
...notebookComponents,
};
}⚠️ Turbopack Compatibility
@next/mdx is not compatible with Turbopack (the default bundler in Next.js 15+). You must use webpack:
# Dev
next dev --webpack
# Or set in package.json
"dev": "next dev --webpack"Usage
Works with both Pages Router (pages/) and App Router (app/) in Next.js.
📖 Nextra
Status: ✅ Supported
notebook-mdx works with Nextra v4 on Next.js 15.
Installation
npm install notebook-mdx nextra nextra-theme-docsConfiguration
// next.config.mjs
import nextra from 'nextra'
import { remarkNotebook } from 'notebook-mdx/server'
const withNextra = nextra({
mdxOptions: {
remarkPlugins: [remarkNotebook],
},
})
export default withNextra({})Component registration
// mdx-components.jsx
import { useMDXComponents as useNextraMDXComponents } from 'nextra/mdx-components'
import { notebookComponents } from 'notebook-mdx/client'
export function useMDXComponents(components) {
return useNextraMDXComponents({
...notebookComponents,
...components,
})
}⚠️ Turbopack incompatibility
Same as Next.js + @next/mdx — Turbopack silently drops remark plugins (Next.js 15) or throws a hard error (Next.js 16). Always run without Turbopack:
next dev --webpack
# or in package.json: "dev": "next dev --webpack"⚠️ Next.js 16 not supported
Nextra v4 + Next.js 16 has an RSC/SWC bug unrelated to notebook-mdx. Use Next.js 15.
📘 Docusaurus
Status: ✅ Supported
notebook-mdx works with Docusaurus v3 using its built-in MDX and remark pipeline.
Installation
npm install notebook-mdxConfiguration
1. Add remark plugin to your preset
// docusaurus.config.js
import { remarkNotebook } from 'notebook-mdx/server';
export default {
presets: [
['@docusaurus/preset-classic', {
docs: {
remarkPlugins: [remarkNotebook],
},
blog: {
remarkPlugins: [remarkNotebook],
},
}],
],
};2. Register MDX components via swizzling
Docusaurus uses a "swizzle" pattern to extend MDX components. Create or update src/theme/MDXComponents.js:
// src/theme/MDXComponents.js
import MDXComponents from '@theme-original/MDXComponents';
import { notebookComponents } from 'notebook-mdx/client';
export default {
...MDXComponents,
...notebookComponents,
};3. Use in your MDX files
---
title: My Tutorial
---
# Data Analysis
:::notebook{file="./example.ipynb"}
:::Project Structure
my-docusaurus-site/
├── docs/
│ ├── tutorial.mdx
│ └── examples/
│ └── example.ipynb # Notebooks alongside content
├── src/
│ └── theme/
│ └── MDXComponents.js # Component registration
└── docusaurus.config.js📙 VitePress
Status: ❌ Not Supported
VitePress uses markdown-it (not remark/unified) and Vue 3 (not React). notebook-mdx remark plugins cannot be used in VitePress's pipeline.
Supporting VitePress would require a separate Vue component library and a markdown-it plugin — a significant effort with a different architecture. If you need VitePress support, open an issue to express interest.
📕 GitBook
Status: 🚧 Planned
GitBook integration is under consideration:
- Block-based notebook rendering
- Collaborative editing support
- Version control integration
📗 Astro
Status: ✅ Supported
notebook-mdx works with Astro via @astrojs/mdx and @astrojs/react.
Installation
npm install notebook-mdx @astrojs/mdx @astrojs/reactConfiguration
// astro.config.mjs
import { defineConfig } from 'astro/config';
import mdx from '@astrojs/mdx';
import react from '@astrojs/react';
import { remarkNotebook } from 'notebook-mdx/server';
export default defineConfig({
integrations: [
react(),
mdx({
remarkPlugins: [remarkNotebook],
}),
],
});Component registration
Astro lowercases MDX component names when resolving them, so you must use notebookComponentsAstro (with lowercase keys) instead of notebookComponents:
---
// src/pages/my-doc.mdx
---
import { notebookComponentsAstro } from 'notebook-mdx/client';
export const components = notebookComponentsAstro;
# My Doc
:::notebook{file="./example.ipynb"}
:::⚠️ Per-page component registration
Unlike Next.js or Fumadocs where components are registered globally, Astro requires you to export components from each MDX page that uses notebooks.
📘 Gatsby
Status: ✅ Supported
notebook-mdx works with Gatsby v5 + gatsby-plugin-mdx, but requires a specific remark-directive version due to a unified version mismatch.
Installation
npm install notebook-mdx gatsby-plugin-mdx gatsby-source-filesystem
npm install remark-directive@2 # Must be v2 — Gatsby uses @mdx-js/mdx@2 (unified@10), remark-directive@3+ requires unified@11⚠️ Use remarkNotebookDirective, not remarkNotebook
remarkNotebook internally bundles remark-directive@4 which will crash in Gatsby. You must use remarkNotebookDirective with remark-directive@2 explicitly:
Configuration
// gatsby-config.mjs
import { fileURLToPath } from 'url'
import { dirname, resolve } from 'path'
import remarkDirective from 'remark-directive' // v2 installed above
import { remarkNotebookDirective } from 'notebook-mdx/server'
const __dirname = dirname(fileURLToPath(import.meta.url))
const config = {
plugins: [
{
resolve: 'gatsby-source-filesystem',
options: {
name: 'pages',
path: resolve(__dirname, 'src/pages'), // Required for gatsby-plugin-mdx
},
},
{
resolve: 'gatsby-plugin-mdx',
options: {
mdxOptions: {
remarkPlugins: [remarkDirective, remarkNotebookDirective],
},
},
},
],
}
export default configComponent registration
Gatsby uses wrapRootElement in both gatsby-browser.js and gatsby-ssr.js:
// gatsby-browser.js (and gatsby-ssr.js — same content)
import React from 'react'
import { MDXProvider } from '@mdx-js/react'
import { notebookComponents } from 'notebook-mdx/client'
export const wrapRootElement = ({ element }) => (
<MDXProvider components={notebookComponents}>{element}</MDXProvider>
)🔧 Custom Framework Integration
If you're using a different framework or want to integrate notebook-mdx manually:
Requirements
Your framework needs:
- MDX support with remark plugins
- React/JSX rendering capability
- File system access during build
Integration Steps
- Follow the General Setup section above
- Configure your framework's MDX processor to use the remark plugins
- Add the React components to your MDX component mapping
Need Help?
If you're working on integration with a framework not listed here:
- 🐙 GitHub: Open an issue
📊 Framework Comparison
| Framework | Status | Difficulty | Notes |
|---|---|---|---|
| Fumadocs | ✅ Ready | Easy | Full support |
| Next.js + MDX | ✅ Ready | Easy | Use --webpack (Turbopack incompatible with @next/mdx) |
| Docusaurus | ✅ Ready | Easy | Full support |
| Nextra | ✅ Ready | Easy | Use --webpack; Next.js 15 only |
| Astro | ✅ Ready | Easy | Use notebookComponentsAstro for component registration |
| Gatsby | ✅ Ready | Medium | Use remarkNotebookDirective + remark-directive@2 (unified@10) |
| VitePress | ❌ Not supported | — | Uses markdown-it + Vue, incompatible architecture |
| GitBook | 🤔 Evaluating | Hard | Block system |
🎯 Recommended Workflow
- Start with Fumadocs if you're building a new documentation site
- Use Next.js + MDX for existing Next.js applications
- Use Nextra for Next.js with a built-in docs theme
- Use Astro or Docusaurus for other React-based doc sites
- Request integration for your preferred framework via GitHub issues
Have questions about framework integration? Check our GitHub Discussions or open an issue.