next.js icon indicating copy to clipboard operation
next.js copied to clipboard

(`@next/mdx`) Default value of `providerImportSource` is incompatible with `app` dir / React Server Components

Open michaeloliverx opened this issue 3 years ago • 2 comments

Verify canary release

  • [X] I verified that the issue exists in the latest Next.js canary release

Provide environment information

    Operating System:
      Platform: darwin
      Arch: arm64
      Version: Darwin Kernel Version 21.6.0: Mon Aug 22 20:19:52 PDT 2022; root:xnu-8020.140.49~2/RELEASE_ARM64_T6000
    Binaries:
      Node: 16.13.1
      npm: 8.1.2
      Yarn: 1.22.19
      pnpm: 6.24.2
    Relevant packages:
      next: 13.0.1-canary.0
      eslint-config-next: 13.0.0
      react: 18.2.0
      react-dom: 18.2.0

What browser are you using? (if relevant)

No response

How are you deploying your application? (if relevant)

No response

Describe the Bug

https://github.com/vercel/next.js/pull/39954 configured the next/mdx package to use { providerImportSource: '@mdx-js/react' } by default which doesn't work with the new app directory introduced in Next 13.

Using the default value above, importing an .mdx file and rendering it inside a server component causes the following error:

TypeError: react__WEBPACK_IMPORTED_MODULE_0__.createContext is not a function

This is because of this line in @mdx-js/react:

  const contextComponents = React.useContext(MDXContext)

Setting { providerImportSource: undefined } fixes the issue and allows rendering MDX components inside server components.

Expected Behavior

Don't default to using config that doesn't work inside server components and let the user decide what behaviour they want.

Link to reproduction

https://stackblitz.com/edit/vercel-next-js-c3fzge?file=next.config.mjs

To Reproduce

Go to StackBlitz link and run npm run dev and try and view the index page.

michaeloliverx avatar Oct 29 '22 19:10 michaeloliverx

Adding onto this because it's somewhat related.

Is there currently no way to use MDXProvider's custom components without client-side rendering? It seems a little bit silly that I would need to mark all of my MDX pages with the use client directive just to replace links with next/links.

Lakuna avatar Nov 11 '22 23:11 Lakuna

Adding onto this because it's somewhat related.

Is there currently no way to use MDXProvider's custom components without client-side rendering? It seems a little bit silly that I would need to mark all of my MDX pages with the use client directive just to replace links with next/links.

A work around would be to pass components via the components prop. e.g.

import Link from "next/link";
import MDXContent from "./content.mdx";

export default function Page() {
  return (
    <main>
      <MDXContent
        components={{
          a: (props) => <Link {...props} />,
        }}
      />
    </main>
  );
}

michaeloliverx avatar Nov 16 '22 15:11 michaeloliverx

I think we can write a custom webpack loader to add the use client directive.

See sample project: next-13-mdx

XDean avatar Jan 10 '23 01:01 XDean

Latest canary release includes a fix to run MDX components on the server https://github.com/vercel/next.js/pull/44651

michaeloliverx avatar Jan 10 '23 09:01 michaeloliverx

#44651 should be enough to close this issue. Only thing missing is docs so I'll mark it as docs related now 👍

timneutkens avatar Jan 10 '23 10:01 timneutkens

Updated

Looks like mdx support with "app dir" is provided by mdxjs-rs and:

This project does not yet support plugins. To benefit from the unified (remark and rehype) ecosystem, use @mdx-js/mdx.


Original question

I'm not sure how to make use of remark or rehype plugins with the new app dir? They seem to be ignored? If we put this in your next.config.js in the example:

const withMDX = mdx({
  options: {
    remarkPlugins: [
      remarkGfm
    ],
  },
})

It doesn't actually do anything?

morgs32 avatar Jan 29 '23 22:01 morgs32

Interestingly, moving to the canary worked for me, but now Tailwind isn't loading. For me, my guess is that adding

{
  "experimental": {
    "turbo": {
      "loaders": {
         ".mdx": ["@mdx-js/loader"]
      }
    }
  }
}

... to my next.config.js has overridden the default loaders?

RobbieMcKinstry avatar Feb 14 '23 21:02 RobbieMcKinstry

FWIW I figured out that the issue was Turbopack. I think the Turbopack loaders were overriden.

RobbieMcKinstry avatar Feb 16 '23 18:02 RobbieMcKinstry

Here's the docs for MDX with app: https://beta.nextjs.org/docs/guides/mdx#mdx

timneutkens avatar Feb 18 '23 08:02 timneutkens

This closed issue has been automatically locked because it had no new activity for a month. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you.

github-actions[bot] avatar Mar 20 '23 12:03 github-actions[bot]