Skip to content

Add rehype-mdx-toc to export toc into MDX module#203

Closed
boning-w wants to merge 2 commits into
rehypejs:mainfrom
boning-w:patch-1
Closed

Add rehype-mdx-toc to export toc into MDX module#203
boning-w wants to merge 2 commits into
rehypejs:mainfrom
boning-w:patch-1

Conversation

@boning-w

@boning-w boning-w commented Jul 3, 2025

Copy link
Copy Markdown

Initial checklist

  • I read the support docs
  • I read the contributing guide
  • I agree to follow the code of conduct
  • I searched issues and discussions and couldn’t find anything or linked relevant results below
  • I made sure the docs are up to date
  • I included tests (or that’s not needed)

Description of changes

I wrote a rehype plugin rehype-mdx-toc that allows users to export the table of contents (TOC) data as a named export from an MDX module.

Why another table of contents plugin?

Since MDX supports exporting data from MDX modules, it's much more convinent to export the TOC — so that users can use it whatever they like, just like with remark-mdx-frontmatter.

Simple usage:

import { compile, run } from "@mdx-js/mdx";
import rehypeMdxToc from "rehype-mdx-toc";
import * as runtime from "react/jsx-runtime";

const mdxContent = `
# Heading 1
## Heading 2
### Heading 3
`;

const compiled = await compile(mdxContent, {
  outputFormat: "function-body",
  rehypePlugins: [rehypeMdxToc],
});
const result = await run(compiled, { ...runtime });
const toc = result.toc;
console.log(toc);

With some bundlers — like @mdx-js/esbuild, @mdx-js/rollup, and @mdx-js/loader, we can easily import the TOC data at build time:

import MDXContent, { toc } from "./you-mdx-file.mdx";

boning-w added 2 commits July 3, 2025 22:35
Signed-off-by: boning-w <wang.boning@outlook.com>
Signed-off-by: boning-w <wang.boning@outlook.com>
@github-actions github-actions Bot added 👋 phase/new Post is being triaged automatically 🤞 phase/open Post is being triaged manually and removed 👋 phase/new Post is being triaged automatically labels Jul 3, 2025
@codecov

codecov Bot commented Jul 3, 2025

Copy link
Copy Markdown

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 100.00%. Comparing base (9bc5528) to head (d28659c).
Report is 26 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff            @@
##              main      #203   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files            6         6           
  Lines          154       163    +9     
=========================================
+ Hits           154       163    +9     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@boning-w boning-w changed the title Patch 1 Add rehype-mdx-toc to export toc into MDX module Jul 3, 2025

@ChristianMurphy ChristianMurphy left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for sharing @boning-w!

Some suggestions:

@boning-w

boning-w commented Jul 4, 2025

Copy link
Copy Markdown
Author

Hi @ChristianMurphy, I really appreciate for your code review.

  • I have updated the dependencies versions to 'x.0.0'.
  • I added Biome as a lint checker, and added it in the test script:
    "test": "npx @biomejs/biome check ./src ./test && node --test".
  • I removed the unnecessary options from tsconfig.json and also remove skipLibCheck.

Regarding:

The default option is to provide a fallback value for users when there are no headings in Markdown contents. By default. it is undefine, but maybe users want to configure their own default value when no headings are found. Since the value could be undefine, [] or others, I use the type unknown.

I commited these changes and published a new version v1.1.0 to npm.

Here is the new version.

@remcohaszing

Copy link
Copy Markdown
Member

Thanks! Your plugin looks really cool!

I just don’t think this is the right place to list it. None of the MDX specific plugins are listed in the rehype or remark plugin lists. A better place would be https://mdxjs.com/docs/extending-mdx/#list-of-plugins.

@boning-w

boning-w commented Jul 4, 2025

Copy link
Copy Markdown
Author

Got it! I may create a pull request there. Should I cloes this pull request?

@remcohaszing

Copy link
Copy Markdown
Member

Let’s have another maintainer close it if they agree with me. :)

@JounQin

JounQin commented Jul 4, 2025

Copy link
Copy Markdown
Member

I agree it should be listed as a mdx specified plugin instead.

@wooorm

wooorm commented Jul 4, 2025

Copy link
Copy Markdown
Member

I’ll close this here. Yes, please do add it there! Thanks everyone!

@wooorm wooorm closed this Jul 4, 2025
@github-actions

This comment has been minimized.

@wooorm wooorm added the 👀 no/external This makes more sense somewhere else label Jul 4, 2025
@github-actions github-actions Bot added 👎 phase/no Post cannot or will not be acted on and removed 🤞 phase/open Post is being triaged manually labels Jul 4, 2025
@boning-w
boning-w deleted the patch-1 branch July 5, 2025 03:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

👀 no/external This makes more sense somewhere else 👎 phase/no Post cannot or will not be acted on

Development

Successfully merging this pull request may close these issues.

5 participants