-
Notifications
You must be signed in to change notification settings - Fork 10.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Using React components in Markdown source #312
Comments
That is a great idea. I would be willing to work on if it's not available yet. |
I the developer of reactdown. It would be awesome to see reactdown working with Gatsby. Ping me if you have questions or need some assistance regarding integrating it. |
👍 this is a common request so would be great to have something working that's widely available! |
I set up a quick and dirty example repository of how to get reactdown working with gatsby. It's good to note that under the hood gatsby is just a very user friendly wrapper on top of webpack, so all of the power is still there to do just about anything. |
Thanks, I will try it and will let you know how it went. |
Oh cool! Nice Ben. That's a lot simpler to setup than I'd been imaging On Tue, Jun 7, 2016 at 10:31 PM Jo Meenen [email protected] wrote:
|
@benstepp nice! This looks straightforward enough when using Markdown files through a wrapper, but would this also work when importing the markdown file to use inside a React component? Edit: it seems like it should just work out of the box, but somehow the React component the |
I'm been thinking about a different approach that the new GraphQL layer (#420) opens up. I opened an issue asking about it in the mdash repo syntax-tree/mdast#13 |
That'd be awesome! I felt I was so close with Reactdown though… The markdown files are properly transformed into React components by webpack (at least it looks like it), but it just gives me empty components when I use them in my code. |
@SachaG have a repo somewhere I can took a look at? |
Wow, really weird. I was trying to create a reproduction of the issue, and now it works! Not even sure what changed… Can't complain I guess :) |
The gods of React came down in a golden chariot, and lo! the code worked |
@SachaG I remember there were some issues with how reactdown references its runtime. Anyway if you hit some issues I would be flat do help. |
Hello! Has there been any recent updates to this? What is the recommended method of using react components in markdown? Is there an example I can follow? Thanks! |
Not yet :-( I have a good plan for how to do it — basically compile the markdown file into a React component file where you handle importing correctly all the referenced React components but haven't needed to build it quite yet. Feel free to start working on it if you need it! |
@KyleAMathews do you mean I should run a converter script on my markdown file and then manually add the other react components I need to the output file produced by the conversion step? Once this is done then do the final build? |
This would ideally be a plugin for Gatsby v1 that would do these steps
automatically.
…On Tue, May 2, 2017, 12:50 PM Piyush Singh ***@***.***> wrote:
@KyleAMathews <https://github.com/KyleAMathews> do you mean I should run
a converter script on my markdown file and then add the other react
components I need to the output file produced by the conversion step? Once
this is done then do the final build?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#312 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAEVh4riB8uXgeRUybcR6OxsC1EAKnkKks5r14kPgaJpZM4Iubim>
.
|
A simple example of what I mean. Imagine you had a markdown file at /my-blog/index.md that looked like the following: ---
title: "hi folks"
---
# This is my broomstick
Yo yo foo
<SweetComponent props="super cool" />
The body could then get converted into a react component which would get run through webpack/babel/etc. as normal. import React from 'react'
import SweetComponent from 'auto-resolve-this-somehow'
class MarkdownBody extends React.Component {
render () {
return (
<div>
<h1>This is my broomstick</h1>
<p>Yo yo foo</p>
<Sweet Component props="super cool" />
</div>
)
}
} The trick part is how to integrate this with Gatsby's graphql system. Ideally you could just query for the "component" version of a markdown file similar to how you can query for the html today. Anyways, that's a brief sketch of what I've thought about. |
@KyleAMathews thanks, I think I get the idea now. My aim is to be able to write content like this which leverage MathJax, D3.js visualisations and could also incorporate Three.js animation components within the markdown source. If you see the html source here the page uses jQuery for some of the control sliders, though I imagine there might be better ways of doing jQuery stuff with React components? From what I gather so far, I imagine producing such content with the Gatsby framework is achievable in a much neater and structured way, is that right? I'm new to web development, but doing my best to learn how the Gatsby system works so that I can contribute to achieving these sorts of goals... |
@KyleAMathews, I've been thinking about your proposed solution.. Do you think something like markdown-it-jsx could be used or improved upon to perform conversion to the desired MD JS component structure? For resolving I'm going to start working on this so any feedback would be awesome! |
Just a note there is another project which is doing this, maybe it will be useful as reference: react-styleguidist. Example of markdown file Enabling components in markdown reminds me this masterpiece by Bret Victor. UPD: and one more example: mdxc And another one http://thejameskyle.com/react-markings.html |
A solution is using One disadvantage: It's of course slower than just using
One way to speed this up would be to not send the raw html with the graphql query, but actually send a format that the Inferno.js docs are using, as described here. As I currently can't find the time to do this last step of optimization, anybody who is interested in it could go this approach. That would mean to
|
Another option I've been eyeing is https://github.com/mapbox/jsxtreme-markdown We could use a similar pattern. Just convert markdown to JSX components. Use custom delimiters to add JavaScript and JSX. We could use our existing Remark setup just fine. And there wouldn't be much of a performance penalty as it'd just be normal React pages. |
There is also https://github.com/cerebral/marksy, which I used recently to good effect. |
Is there a recommended approach for this in the context of Gatsby or is it still to be decided? |
Hi, any recommendation to include customs components in our gatsby markdown files ? |
One more option into the collection https://idyll-lang.github.io/ |
Looks like marksy works nicely for that use case as it returns a react elements tree, i'm wondering how i could integrate that into a gatsby plugin ? |
@KyleAMathews @revolunet What do you think about registering the components we need to use as custom elements, afterwards we can simple include them within the blog post and leave the rest of the work for browser to do? This would eliminate any need to parse markdown as a react tree and keep our application performant, however, I don't know if there's going to be a performance cost, to do |
@avigoldman any news on the Gatsby 2 plugin? It would also be awesome if you could give rough directions on how you would build it without the layout component that doesn't exist in Gatsby 2 anymore. |
I was hoping I could somehow use the |
If my PR gets merged (mdx-js/mdx#189), I think we'll be able to use MDX with existing gatsby-plugin-mdx and gatsby-transformer-mdx. The only required change will be on our end, and that's exporting our post template from our
const path = require('path')
exports.createPages = ({ actions }) => {
actions.createPage({
path: '/posts/hello-world',
component: path.join(__dirname, 'src', 'posts', 'hello-world.mdx'),
context: { /* passed as pageContext */ }
})
}
import React from 'react'
import Layout from './layout'
export default ({ children, pageContext }) => (
<Layout>
{children}
</Layout>
) |
I think this is really critical. Right now all the |
@DylanVann that kinda depends. |
Ideally of course we blend the both of both worlds. |
@KyleAMathews Yeah it would mean some more JS on the client side, although it would still be first delivered as static HTML. I think a lot of people are probably shipping I do understand that there is utility in the I've got this sort of working with the |
It seems that way, but in practice it's much more complicated. If you believe you're onto something, you could raise a new issue with a focused proposition. |
It seems like a hard problem to solve. Unfortunately I don't think I'll have time to implement anything or make a proposal. The idea of doing This is generated by export const videoHTML = ({
srcVideo,
srcVideoPoster,
base64,
paddingBottom,
presentationWidth,
}) =>
`<cloud-video srcvideo="${srcVideo}" srcvideoposter="${srcVideoPoster}" base64="${base64}" paddingbottom="${paddingBottom}" presentationwidth="${presentationWidth}"></cloud-video>` Then using a custom component with import React from 'react'
import rehypeReact from 'rehype-react'
import CloudVideo from './CloudVideo'
const renderAst = new rehypeReact({
createElement: React.createElement,
components: {
'cloud-video': CloudVideo,
},
}).Compiler
const Markdown = ({ ast }) => renderAst(ast)
Markdown.propTypes = {
ast: PropTypes.object,
}
export default Markdown The ast can be pulled out of GraphQL. So this component works for SSR and client side. Anyways I know how it is with OSS. I'm just saying I think it would be a great feature and could reduce code complexity, so it would be great if anyone has time to figure out better solutions. |
I'm not disagreeing with anything you are saying, I think that starting a good discussion would be much better in its own issue, rather than at the end of a very loaded thread of 60+ comments. 😉 |
Me and @avigoldman built gatsby-mdx to house ambitious 2.0 compatible MDX integrations and utils. Currently gatsby .mdx pages work by default after enabling the plugin and the following additional features have been added on top of mdx:
We're also planning more sophisticated integrations for
We're still pretty early in the lifecycle, so let us know if you run into any issues and we'll get it done :) |
@ChristopherBiscardi is it meant to be used in combination with gatsby-plugin-mdx or instead of it? |
@silvenon It looks like gatsby-plugin-mdx will be deprecated and thus stop at 1.0, while gatsby-mdx will move forward with 2.0 and beyond. |
@m-allanson think its safe to close this issue now that we have gatsby-mdx? |
I think so, thanks everyone 🎉 |
So is If the answer is not a clear-cut yes, could someone explain the advantages and drawbacks of both approaches? |
I think this part of that blog post answers your question. rehype-react provides custom HTML elements which map to React components, but MDX actually is JSX inside Markdown, it's more predictable and has less caveats. I'm not in the Gatsby team, but I would say yes, gatsby-mdx is the preferred way of React in Markdown. |
@janosh as far as I know gatsby-mdx can't replace gatsby-transformer-remark completely yet But if you're not in the need of those plugins or can wait then I would say yes, at least I'll prefer it, seems cleaner to me |
@CanRau I'm rebasing that today (ChristopherBiscardi/gatsby-mdx#68) with the intent to merge and release. There will probably be some edge cases we have to deal with but I'll be going over some of them today on stream before I merge. The state of the PR is that gatsby-remark-* plugins are applied properly, but there are differences in how the output of say, the gatsby-remark-prismjs plugin (which currently produces HTML output) is handled by transformer-remark vs mdx's pipeline. I view support for plugins like gatsby-remark-prismjs as important, but also a suboptimal approach. A better approach in the MDX world is to use something like prism-react-renderer as the I'm far more concerned with the copy-linked-files and image processing working than I am with prismjs working for the first release of gatsby-remark-* plugin support. |
Sounds awesome @ChristopherBiscardi especially copy-linked-files and image support, I would love to help but realistically speaking I don't think I can handle it right now as we're really packed^^ interesting to know that you're streaming your work..I'm quite new to live stuff and don't yet understand how to know when you're going life..probably works only with an account I guess |
Happy to have you help at any point in the future if you find the time, feel free to ping me if you have questions :) Feedback itself helps a bunch either way though so if you try it out be sure to file issues!
I set up a "calendar" of streaming times at the bottom of my twitch channel. I know if someone has a twitch account and they follow me they'll get notifications when I go live, but otherwise the schedule is where to look. Pretty sure you can watch whether you have an account or not. I'm a bit new to streaming myself (only been doing it a couple weeks now) so always open to better ways to do this kind of stuff. I've had a few people come around repeatedly and hang out/watch/talk in chat which is pretty fun :) |
kay got it, good to know and I'll surely post issues when I encounter any ;) |
Btw, since Prism was mentioned, I'd just like to add that ideally remark/rehype plugins should be used directly, MDX supports that via |
yeah, totally. gatsby-mdx already supports passing remark/rehype plugins through to mdx core. Here's @mapbox/rehype-prism for example (I yanked that example from some of your PR/Issue discussions originally @silvenon, thanks). AFAIK rehype prism doesn't support prism plugins so it's always a tradeoff depending on use cases (I believe using rehype plugins for prism means you will have a harder time integrating something like react-live, for example) gatsby-remark-prismjs and other gatsby-remark-* plugin support was released in 0.1.1 today, so now there's at least 3 options for syntax highlighting between rehype/remark/react-components 😝 |
Is there an easy way to use React components in my Markdown source. Something like reactdown?
The text was updated successfully, but these errors were encountered: