question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Feature Request: Building MDX Pages via `getStaticProps`

See original GitHub issue

Feature request

Given that Next.js is investing efforts into static generation with the likes of getStaticProps and getStaticPaths, it would be great to leverage the full power of MDX without being tied to the Webpack loader’s (@next/mdx) current constraints.

The current use of @next/mdx has its limitations:

  • Constrained to a single layout
  • No ability to transform MDX to HTML for content feeds (e.g. RSS)
  • No ability to parse frontMatter
  • No ability to fetch from remote sources (e.g. CMS)
  • Difficult to transform raw content

next-mdx-enhanced does a great job of alleviating some of these concerns but still relies heavily on Webpack, rather than utilizing Next’s static functions.

This PR suggests @next/mdx could be extended to offer users more flexibility (but hopefully still easy-to-follow) on how their pages are built. This suggestion aims to provide:

Describe the solution you’d like

Note: These examples would still rely on the consumer configuring their own MDXProvider (e.g. Theme-UI)

  1. An MDXRenderer that allows for full control of layout:

    (Importing an mdx file would return an object containing frontMatter and mdxContent)

    // e.g. src/pages/blog/[id].tsx
    import * as React from "react";
    import { GetStaticProps, GetStaticPaths, NextPage } from "next";
    import Error from "next/error";
    import LayoutPost from "../layouts/post";
    import { somePrivateFunctionToGlobMdxFileNames } from "./utils";
    // but maybe this could be a function added to `@next/mdx`
    
    // Proposed:
    import { MDXRenderer } from "@next/mdx";
    
    type BlogPostProps = { error?: boolean };
    
    export const getStaticPaths: GetStaticPaths = async () => ({
      paths: somePrivateFunctionToGlobMdxFileNames("../posts"),
    });
    
    export const getStaticProps: GetStaticProps<BlogPostProps> = async (
      context
    ) => {
      // this could also be a remote data source
      const res = await import(`../posts/${context.params.id}.mdx`);
      // const { frontMatter, mdxContent } = res
    
      return { props: res || { error: true } };
    };
    
    const BlogPost: React.FC<NextPage & BlogPostProps> = ({ error, ...props }) =>
      error ? (
        <Error statusCode={404} />
      ) : (
        <LayoutPost title={props.frontMatter.title}>
          <MDXRenderer {...props} />
        </LayoutPost>
      );
    
    export default BlogPostPage;
    
  2. An mdxToStaticMarkup function that allows the MDXRenderer to be converted to static HTML (for RSS feeds etc.).

    mdxToStaticMarkup(<MDXRenderer />);
    

    With this approach the consumer would have the freedom to transform content if necessary.

Describe alternatives you’ve considered

One approach I tried back in january was to use MDX’s async API in the getStaticProps method directly, but I hit a snag with this issue: https://github.com/mdx-js/mdx/issues/382#issuecomment-523014913

More importantly though, given Next.js does such a great job of reducing set-up complexity, it would be great to have something that makes MDX more flexible but still easy to use.

Additional context

As of now my availability is open and I would be more than happy to collaborate with the Next.js core team into spiking this as an option (if desired).

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:6
  • Comments:12 (10 by maintainers)

github_iconTop GitHub Comments

1reaction
deadcoder0904commented, Oct 17, 2020

Would love to see this implemented as well.

I tried using next-mdx-remote & next-mdx-enhanced but ran into its limitations (specifically having images in the same folder as the posts that it cannot solve)

I had to use hacks to solve MDX to HTML (for RSS) → https://github.com/vercel/next.js/discussions/17931

1reaction
joe-bellcommented, Jun 30, 2020

Gotcha, thanks for the explanation

Do the Next.js core team plan on integrating something similar to next-mdx-remote in the future?

I do feel that something like this is more inline to what Next.js is achieving in other areas, it would be great to see this for MDX too

Read more comments on GitHub >

github_iconTop Results From Across the Web

Data Fetching: getStaticProps - Next.js
Fetch data and generate static pages with `getStaticProps`. ... Next.js will pre-render this page at build time using the props returned by getStaticProps...
Read more >
Building a Blog With Next.js and MDX | The WebStorm Blog
It houses our app's cache, server, and static files. Pages and routing. The pages directory houses the different pages for our app. The...
Read more >
Making a blog with Directus, MDX, and Next.js On-Demand ISR
Today we look at building a blog with Directus and Next.js. We will use MDX to store our blog content in Directus. We...
Read more >
Use MDX in Next.js to Dynamically Create Pages for a Blog
Learn how to source MDX content in Next.js to dynamically create pages for a blog.
Read more >
How to get exports form mdx in nextjs - Stack Overflow
However I can't seem to get at data exported in such a way. For instance using the following /* -- ./pages/example.mdx -- */...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found