Parsing MDX files with mdx-bundler

1

Install the dependencies for mdx-bundler

Terminal
# If you're using npm
npm install mdx-bundler esbuild

# If you're using yarn
yarn add mdx-bundler esbuild
2

Create a directory with MDX files

Terminal
\posts
  \file-1.mdx
  \file-2.mdx
  \file-3.mdx
3

Install necessary Plugins

Terminal
# If you're using npm
npm install reading-time gray-matter rehype-slug rehype-code-titles rehype-autolink-headings rehype-prism-plus

# If you're using yarn
yarn add reading-time gray-matter rehype-slug rehype-code-titles rehype-autolink-headings rehype-prism-plus
4

Parse all MDX files

mdx.js
import matter from 'gray-matter';
import { join } from 'path';
import readingTime from 'reading-time';
import { readdirSync, readFileSync } from 'fs';

import { bundleMDX } from 'mdx-bundler';

import rehypeSlug from 'rehype-slug';
import rehypeCodeTitles from 'rehype-code-titles';
import rehypeAutolinkHeadings from 'rehype-autolink-headings';
import rehypePrism from 'rehype-prism-plus';

export async function getFiles() {
  return readdirSync(join(process.cwd(), 'posts'));
}

export async function getFileBySlug(slug) {
  const source = readFileSync(
    join(process.cwd(), 'posts', `${slug}.mdx`),
    'utf8'
  );

  const { code, frontmatter } = await bundleMDX(source, {
    xdmOptions(options) {
      options.rehypePlugins = [

        // some good and popular plugins
        ...(options?.rehypePlugins ?? []),
        rehypeSlug,
        rehypeCodeTitles,
        rehypePrism,
        [
          rehypeAutolinkHeadings,
          {
            properties: {
              className: ['heading_title']
            }
          }
        ]
      ];
      return options;
    }
  });

  return {
    code,
    frontMatter: {
      wordCount: source.split(/\s+/gu).length,
      readingTime: readingTime(source),
      slug: slug || null,
      ...frontmatter
    }
  };
}

export async function getAllFilesFrontMatter() {
  const files = readdirSync(join(process.cwd(), 'posts'));

  return files.reduce((allPosts, postSlug) => {
    const source = readFileSync(
      join(process.cwd(), 'posts', postSlug),
      'utf8'
    );
    const { data } = matter(source);

    return [
      {
        ...data,
        slug: postSlug.replace('.mdx', ''),
        readingTime: readingTime(source)
      },
      ...allPosts
    ];
  }, []);
}