This article is a part of the series "Creating a blog with React"
- I'm playing with Remix
- How to configure Remix and mdx-bundler (with file system access)
- How to configure Remix and mdx-bundler for a serverless platform - barrel files approach, Remix v1
- Adding dark mode to a blog - how to avoid flashes of the wrong theme
- Migrating from Remix to NextJS
- I'm going off MDX for blogging
How to configure Remix and mdx-bundler (with file system access)
The MDX Bundler solution requires server-side file system access, and as such is not suitable for serverless application deployments using services like AWS Lambda or Netlify.
If you need a solution for a tool like Netlify, see this post.
This post outlines a process I took to improve this blog, although I ultimately abandoned this approach due to the requirement to have access to the file system.
Starting Point - The Old Way - Configuring via Remix's mdx option.
Initially I had followed Remix's MDX guide.
We declare .mdx files in our Remix routing structure. Remix's out-of-the-box tooling can handle the the MDX content and at build time converts it to JavaScript where it is treated just like any other ordinary React route component.
Conveniently, YAML frontmatter headers are also supported.
Some configuration is required - we declare Remark and Rehype plugins in the remix.config.js.
Unauthorized. Is your Github token valid?
The Problem
The problem I had is mostly around the usage of frontmatter - I had no control of how the frontmatter behaved with my application; I could only use the functionality as provided with the out-of-the-box tooling - adding titles, social meta tags etc.
One annoying issue I had was that twitter's social meta tags required their own twitter prefix (eg. og:twitter:title), even though this was going to be the exact same as the other socials, I had to go through and specially add frontmatter items for twitter on every post.
But mostly, I wanted to be able to group items in a series - and provide links to the next item in the series etc, all without having to maintain those links everywhere.
Note the nice series box at the top of this page.
Additional functionality might include including an author tag and creation dates.
The Solution
The code blocks in this post come from this very simple Remix application repository here.
A recommended solution by Remix themselves is to use mdx-bundler.
At first I looked at how Kent C. Dodds' builds his blog. But his configuration is complex (eg. see here).
One of the top search results for 'remix mdx-bundler' gives us this Oldweb2 blog post, which is a lot simpler. However, this post is quite out of date. However, it was a useful starting point in understanding the general strategy of using mdx-bundler.
Move all of your MDX files out of the routes directory
You are no longer going to use Remix's out-of-the-box file routing for the blog posts. I moved all my posts from ~/app/routes/test/*.mdx to ~/app/blog-posts/test/*.mdx.
Update your TSConfig if you haven't already
Unauthorized. Is your Github token valid?
The module property will allow us to do dynamic imports later.
Declare .server.ts utility files
Unauthorized. Is your Github token valid?
Unauthorized. Is your Github token valid?
The .server.ts file convention causes Remix to not include this code in client bundles - which is important as these use node packages.
Create a post.tsx utility for parsing the MDX.
Here we load our MDX files at run time and use MDX Bundler to parse them as components and as frontmatter.
Unauthorized. Is your Github token valid?
Create a slug handler
We now handle any requests for our blog posts with $.tsx handler. We just pass the entire slug to our utility function, and ask it to return the component and frontmatter.
Unauthorized. Is your Github token valid?
Unauthorized. Is your Github token valid?
Update any relative imports
Any relative imports may no longer work, as the imports will be relative to the application root, rather than the file doing the importing. So update them accordingly.
Unauthorized. Is your Github token valid?
Update a pages metadata based on frontmatter
Your Remix meta function can use the frontmatter that the loader returned. Use this to update the page meta tags.
Unauthorized. Is your Github token valid?
Create a post header based on the post frontmatter
We can use the loaded frontmatter to create whatever other content (such as tags, author, post title) at the top (and/or bottom) of our post.
Unauthorized. Is your Github token valid?
Create home page list of blog posts
Here we get access the frontmatter across all posts to create a table of contents on our home page.
Unauthorized. Is your Github token valid?
And there you have it!
Questions? Comments? Criticisms? Get in the comments! 👇
Spotted an error? Edit this page with Github