(`@next/mdx`) Default value of `providerImportSource` is incompatible with `app` dir / React Server Components
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.
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.
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 theuse clientdirective just to replace links withnext/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>
);
}
I think we can write a custom webpack loader to add the use client directive.
See sample project: next-13-mdx
Latest canary release includes a fix to run MDX components on the server https://github.com/vercel/next.js/pull/44651
#44651 should be enough to close this issue. Only thing missing is docs so I'll mark it as docs related now 👍
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?
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?
FWIW I figured out that the issue was Turbopack. I think the Turbopack loaders were overriden.
Here's the docs for MDX with app: https://beta.nextjs.org/docs/guides/mdx#mdx
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.