A minimal yet extensible setup for writing and rendering MDX in Next.js.
Includes a feature-rich editor powered by @mdxeditor/editor
and a viewer powered by next-mdx-remote
. Perfect for blogs, documentation, and interactive content.
- Full MDX Support: Markdown + React components in one file
- Rich Editor: Toolbar, lists, tables, images, code blocks, JSX embedding
- Custom Components: Callouts, badges, confetti buttons, etc.
- Syntax Highlighting: Powered by
rehype-highlight
with GitHub themes - Accessible Output: Slugs + autolinked headings for navigation
- Next.js Native: Works with App Router, server actions, and RSC
Make sure you have a Next.js 13+ project:
npx create-next-app@latest mdx-editor-nextjs
cd mdx-editor-nextjs
Install dependencies:
npm install @mdxeditor/editor next-mdx-remote
npm install remark-gfm remark-math
npm install rehype-highlight rehype-slug rehype-autolink-headings
(Optionally add shadcn/ui
for UI components.)
src/components/mdx/mdx-editor.tsx
<MDXEditor
markdown={value}
onChange={setNewContent}
contentEditableClassName="prose max-w-none p-4 focus:outline-none"
plugins={[
headingsPlugin(),
listsPlugin(),
codeBlockPlugin(),
codeMirrorPlugin(),
toolbarPlugin({ toolbarContents: () => <UndoRedo /> }),
]}
/>
src/components/mdx/mdx-viewer.tsx
<MDXRemote
source={content}
options={{
mdxOptions: {
remarkPlugins: [remarkGfm, remarkMath],
rehypePlugins: [rehypeHighlight, rehypeSlug, rehypeAutolinkHeadings],
},
}}
components={mdxComponents}
/>
src/app/page.tsx
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
<MdxEditor value={content} height={600} />
<div className="border rounded-md p-4 h-[600px] overflow-y-auto">
<MdxViewer content={content} />
</div>
</div>
- Callout – info/warning/success/error banners
- Badge – styled text badge
- ConfettiButton – interactive button with confetti 🎉
- Table / Code / Blockquote – styled markdown overrides
- Extend
mdxComponents
inmdx-components.tsx
to override default markdown elements (h1
,p
,a
,table
, etc.) - Add your own JSX components for interactive content.
- Swap out highlight.js themes by importing a different CSS file.
- Remark plugins: Markdown-level (e.g., tables, math, GFM)
- Rehype plugins: HTML-level (e.g., syntax highlighting, slugs, autolinks)
- MDXEditor plugins: UI/UX features inside the editor (toolbar, lists, code blocks)
- Start with minimal plugins; add complexity as needed
- Use
prose
styles from Tailwind for readable output - Define custom components for reusable blog elements
- Keep plugins in the correct order (
rehype-slug
beforerehype-autolink-headings
) - Separate editor and viewer responsibilities cleanly