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;
}