Closed khrome83 closed 6 years ago
I kind of have the same question, I think.
I'd love if it I could access the original node from mdast's AST in my customer component renderer. It seems that it is using a transformed node instead from hast.
mdx
into your code and use it manually when you don't get source from your bundler.
// lib/withComponents.js
const default = { /* ... */ };
const withComponents =
(Mdx, overrides) => <Mdx components={Object.assign(default, overrides)} />
// index.js import hello from './hello.md' import withComponents from './lib/withComponents' const VanillaHello = withComponents(hello); const CustomizedHello = withComponents(hello, { h1: / ... / });
I'm also wondering about point 1. I tried using the sync API, but it produces a string of an ES module.
The MDX README lists "No runtime compilation" as a feature, so I'm guessing this isn't currently possible without babel/webpack.
@johno @timneutkens can you confirm?
I have drawn it out below 😄:
Point 1: So runtime compilation is not possible at the moment. Also because we wouldn't know where the import
statements come from and how to load them.
You could compile external content at build time, however, this is not the responsibility of mdx, mdx takes an mdx string and turns it into an es6 module.
Point 2: like @hawkins said you can implement something yourself. In earlier versions, we depended on React context, but mdx can be compiled to any framework supporting JSX, so we just provide an explicit way to define components. If you want to magically inject components I would recommend doing either a HOC or creating a webpack loader that does this.
Point 3: I'm not sure what you mean exactly, but feel free to write a full spec on what you want in a Next.js issue. Please be very specific as to what you want it to look like so we can consider it 👍
MDX has evolved since this discussion, documentation has improved, Next.js now has a MDX plugin etc. If there are any more questions, open an issue and I would be more than glad to explain everything. 😃
@silvenon Hi! Is the point 1 still not possible with mdx? Is there any other way you can suggest using which I can convert the markdown into JSX at runtime? My other question is, if the markdowns is converted to JSX at compile time, how is it done in the live code editor? Can we use a similar approach?
👋 @msrshahrukh100
Fetching dynamic data and building pages is something that your framework needs to handle, it's slightly outside the scope of MDX core (though we should add docs that point people in the right direction).
Frameworks like Next.js, Gatsby, and React Static provide ways for you to fetch that data and then render MDX documents. I can't remember the last implementation I built with Next.js + Contentful exactly, but I was able to achieve it with a custom server and route setting based on that data for static exports.
With Gatsby + Contentful, you can use the data layer with a GraphQL source and then programmatically create pages using gatsby-mdx.
The live code editor uses: https://mdxjs.com/advanced/runtime
@timneutkens @silvenon This issue is old and forgotten, but the new Next.js SSG support brings it back to life. Because it can compile stuff at build time, Next.js can now be used with MDX to build static pages based on MDX stored on a CMS. It's become technically possible, but there aren't any example of this yet.
Related issues:
Correct me if I'm wrong, but it should be possible now! And coupled with SSG, this opens up some very wide possibilities for ultra-rich content stored on CMS.
I don't know if it'll support advanced SSG features such as revalidate and fallback (but it should IMHO, since it's a full page rebuild, not some "on-the-fly" compilation).
Yeah, I ran into this problem with Next.js as well when I tried to combine MDX with dynamic routes. I think the confusion happens if you forget to view MDX as a JavaScript module, which can happen. Markdown compiles to HTML, so it's totally something that you can put in a CMS, but as Tim illustrated, MDX is JavasScript, which is totally different even though the source file may look the same. Adding MDX content to a CMS makes as much sense as adding JavaScript. Maybe it would be possible to compile the MDX string with Babel and run the JavaScript code with some vm.Module
acrobatics to get the exported component, but the point is that MDX is just not the right tool for this job.
Thanks @silvenon for this clarification! I wish this was clearly stated in the docs as it was a great source of confusion to me.
Since then, I've found a way that doesn't use MDX but markdown-to-jsx
and it works great. I'm able to store HTML/Markdown/JSX in Airtable (or any CMS fields text-based) and made a live example out of it on Next Right Now.
Demo: https://nrn-v2-mst-aptd-at-lcz-sty-c1.vercel.app/fr/examples/built-in-features/md-as-jsx Live example: https://nrn-v2-mst-aptd-at-lcz-sty-c1.vercel.app/fr/terms CMS: https://nrn.my.stacker.app/login?api_token=be1050d1-de5e-4ae0-97c8-030a132f254b&ref=unly-nrn Source code: https://github.com/UnlyEd/next-right-now/tree/v2-mst-aptd-at-lcz-sty
Yay! I'm glad that you found a solution that works for you 👍
@silvenon @Vadorequest I think what you are discussing can be achieved with this library:
https://github.com/hashicorp/next-mdx-remote
What do you think?
Thanks @acaua, I'm not using MDX for this anymore, and I believe using markdown-to-jsx
has fewer downsides than MDX, due to the very way things are handled internally - But I could be wrong, it's only a personal feeling.
I haven't checked how it works, but yes, next-mdx-remote
looks ideal 😃 Reminds me of MDXRenderer
from gatsby-plugin-mdx
. And regarding markdown-to-jsx
, if it works for you then that's the only thing that matters, and it's really lightweight so I bet it's much faster. One of the benefits of MDX is the access to the Unified ecosystem of plugins, and being able to import and export modules, i.e. Babel processing.
This is a cool project, but it is unclear to me how to handle a few use cases. We use react-markdown currently, and moving to MDX with Next would be ideal, if it would support our needs.
Is there currently a way to do the following?
Reference a string as the markdown content so the MD data can come from a source not controlled by babel/webpack. Our use case is that we have markdown coming from a external source in Contentful. Being able to make a call to retrieve the string and then import it would be amazing.
Currently it seems like the way to replace the "renders" for the markdown import is per import basis because the act of importing is creating that JSX looking inclusion. It would be ideal to configure renderers across the entire application, and then override as needed. The use case for this - we use custom components for all markdown renderers, as this allows us to control styling in those components with styled-jsx. So we use the same paragraph, link, heading, etc render in each situation. But declaring it multiple times would be a lot of boilerplate code.
This is less of a MDX issue, but may speak to providing a dynamic interface. Next.js has a wonderful static export setup, and it would be ideal if we could specify a dynamic page in next.js that takes a array of markdown files to create other pages. While this is a hurdle for Next.js, it seems that the import would require the ability to be dynamic, either opening the content seperatly as a string and feeding it in (#1) or some other interface.
Thanks! Just curious thoughts and if this aligns with the goals of the project.