Establishing a public space to talk about what you’re learning is a really helpful way to show proven history around your learnings. To accomplish this we’re going to use next-mdx-remote to source MDX posts locally.

<aside> ❔ MDX is built on top of markdown to allow us to add custom JSX based components for interactivity to our blog posts. Learn more about MDX here

</aside>

Let’s install next-mdx-remote and the supporting packages we’ll need to engage with the contents of our mdx posts

npm i next-mdx-remote gray-matter fast-glob

Now that we have that installed, let’s create a folder to hold our posts inside of.

In our main directory, we can create the posts folder and fill it with our first post introduction.mdx

<aside> 👀 Our main folder structure should look like:

📁 pages 📁 posts 📁 src 📁 public

</aside>

---
title: Intro to my blog
description: This is my first post to my blog to help get me started in writing more consistently and learning in public
date: 1/1/2022
---

Here's some text to help get started in pulling from this page and displaying in my application

In our new file, we’ll create a template to follow as we create new posts. We’re going to want to make sure we have a place to fill in metadata about our posts (things like the date, title, description, and tags are good things to think about)

Since we have some example data to pull against, we can now setup next-mdx-remote to help us setup an authoring flow from our file system.

Inside of utils we’re going to create a new function called getLocalMdx.

// /src/utils/getLocalMdx.js

/*
		I’ve left comments around the code to highlight some parts we really
		need to pay attention to, to understand how this function operates.
*/

// Why do we need these packages and what are they doing for us?
import { promises as fs } from 'fs';
import path from 'path';
import { serialize } from 'next-mdx-remote/serialize';
import matter from 'gray-matter';
import glob from 'fast-glob';

export default async function getLocalMdx(source) {
  const contentGlob = `${source}/**/*.mdx`;
  const files = glob.sync(contentGlob);

  if (!files.length) return [];
	// What is Promise.all doing here? Why do we need it when interacting with the filesystem
  const content = await Promise.all(
    files.map(async (filepath) => {
      const slug = filepath
        .replace(source, '')
        .replace(/^\\/+/, '')
        .replace(new RegExp(path.extname(filepath) + '$'), '');

      const mdxSource = await fs.readFile(filepath);

			// What is next-mdx-remote and gray-matter doing to the data from above? 
      const { content, data } = matter(mdxSource);
      const mdx = await serialize(content, { scope: data });

      return {
        filepath,
        slug,
        content,
        data,
        mdx,
      };
    }),
  );
  return content;
}