MDX Table of Contents

For use with Next.js.

import { MDXProvider } from '@mdx-js/react';
import { MDXComponents } from 'components/MDX/MDXComponents';
import { Toc } from 'components/Toc/Toc';
import * as React from 'react';

export interface MarkdownProps<Frontmatter> {
  meta: Frontmatter;
  children?: React.ReactNode;
}

export default function MarkdownPage<
  T extends { title: string } = { title: string }
>({ children, meta }: MarkdownProps<T>) {
  const anchors = React.Children.toArray(children)
    .filter(
      (child: any) =>
        child.props?.mdxType && ['h2', 'h3'].includes(child.props.mdxType)
    )
    .map((child: any) => ({
      url: '#' + child.props.id,
      depth:
        (child.props?.mdxType &&
          parseInt(child.props.mdxType.replace('h', ''), 0)) ??
        0,
      text: child.props.children
    }));

  return (
    <>
      <MDXProvider components={MDXComponents}>{children}</MDXProvider>
      <Toc anchors={anchors} />
    </>
  );
}

Source: Jared Palmer