Next.js Discord

Discord Forum

How to realize an MDX pages like experience with the App router (Next 13+)

Unanswered
Golden-winged Warbler posted this in #help-forum
Open in Discord
Golden-winged WarblerOP
New to NextJS, Coming from hugo... there are few nice things missing out of the box
1. being able to add a markdown / mdx file and get a new page automatically
2. being able to generate a site tree for side menu navigation, including page weight for ordering
3. draft mode, where certain pages only render & route in development mode, this is helpful for new

1. With the app router, each new markdown page has to be in a separate directory and have 2+ files, a bit tedious but not a deal breaker. I am wondering if there is a way to use something like docs/[[...slug]] and getStaticProps (which obv doesn't work with the app router). I'm not sure if generateStaticParams is sufficient, I'd like to have included extra data or props. While I'm able to load the mdx with a file read, it does not render the same as mdx which is imported like a component. Ideally these mdx only pages could be within the same app folder, but look more like the older pages/ router style (hugo style too), or they could be in a different directory, but the key here is less boilerplate directories & page.tsx files, re: UX / DevX

2. I've resorted to building a JSON object out-of-band with a script and then use this to define the tree for navigation. It basically searches a directory for page.tsx or mdx files, configurable. Ideally, I could get this information from NextJS. Is this possible?

3. I see NextJS has a "draft" mode, but it is different from being able to have draft content mdx files or pages within the code. It seems the NextJS draft mode is more designed for content in a CMS. Still, it does not seem like there is a way to have routes which only show in dev mode. One pattern I like to have is a style guide and other documenation for people working on the site / app, which is only available during development. When building for production, these routes are not included. I can wrap the page.tsx and look for draft mode, and redirect as needed. Is there an easier way to do this?

31 Replies

Asian black bear
You should be able to do the exact thing same as the pages dir with the app dir and a url slug.
With the added bonus that your rendered mdx can be a server component
Golden-winged WarblerOP
How do I import the mdx file based on the slug?
Asian black bear
Basically, move the code in getStaticProps into the async data fetching part of the server component
There are docs about how to do getStaticPaths using some kind of metadata thing
Golden-winged WarblerOP
you mean like the small reference in the docs to having the following at the top of the mdx file?

export const meta = {
  title: "foo",
  weight: 10
}

# markdown content!
I noticed that this works in dev mode, but not when building for production

import Content, { meta } from './content.mdx'
Asian black bear
I am assuming you will need to fetch the markdown data using a facility other than import
But you would have had to using the pages dir too...
Golden-winged WarblerOP
ah, this is what is breaking, because the rendering pipeline is different
Asian black bear
Maybe dynamic import would be worth looking into
Golden-winged WarblerOP
Can I use dynamic imports within the component function? or only at the top of the file, where imports normally go?
or would that component have some way to take the slug and read the file...?

And would caching / SSG pick up on this?
if you want to have a single route page and the .mdx files stored somewhere else, you can use a dynamic import to get the MDX content. this is what I did with my blog: https://github.com/rafaelalmeidatk/rafaelalmeidatk.com/blob/9be13f0f199221344b9b78e24ec3c7b933de0f4a/src/app/blog/%5Bslug%5D/page.tsx#L42-L44
Golden-winged WarblerOP
looks promising! thank you @Rafael Almeida

I will report back later if this works
Golden-winged WarblerOP
So that mostly worked for me, but it seems I've encountered a bug in NextJS, that you (@Rafael Almeida) might also hit because of using next.Link in your components

https://github.com/vercel/next.js/issues/50471
oh thanks for sharing this, I didn't know about this bug
I didn't encountered it yet because my Link component uses a normal a tag when the link is external which is the only type of link I am using at the moment in my blog pages
Golden-winged WarblerOP
I'm using https://codehike.org so hit this. It also is not server component ready because it uses component names like <CH.Spotlight> (the dot is the issue)
i also tried mdx-components.tsx; not sure if thats the recommended fix but i dont think it worked for me
English Lop
@Rafael Almeida did you run into this problem when you were first developing your site? i'm running your site locally on my machine and this error is not occuring, but it is occurring for my site somehow
even though we have basically the same setup
English Lop
nope
my mdx-components.tsx is the default
English Lop
fixed it :]
@English Lop fixed it :]
Siamese Crocodile
Hey, would you mind sharing your solution?
@Siamese Crocodile Hey, would you mind sharing your solution?
English Lop
my next config was set up for pages router
while i was using app router