Voko
Voko

Reputation: 778

How to use a React component inside a Gatsby plugin?

I have a Markdown plugin that fetches the markdown AST and replaces the image nodes by some HTML:

module.exports = ({ markdownAST }) => {
  visit(markdownAST, 'image', node => {
      const html = `...`
      node.type = 'html'
      node.children = undefined
      node.value = html
  })

  return markdownAST
}

Now I don't want only to replace with HTML but I want to replace the images with a full React component. This way, I can write some friendly Markdown like ![](image.png) and it get replaced by a React component via this plugin. I don't want to type JSX inside Markdown, I want to keep the Markdown file as is.

How can I do this? I have a React component in a separate file waiting to be used.

If I used gatsby-plugin-mdx, I could add some React components in Markdown directly:

...
<Image />
...

But I want to keep the Markdown syntax and still use:

...
![](image.png)
...

But I want that behing the scene (in the transformer plugin I'm writing), the image gets converted to a React component and NOT ONLY into some custom HTML as shown above.

Upvotes: 1

Views: 176

Answers (1)

coreyward
coreyward

Reputation: 80041

Gatsby does not provide functionality for storing React component instances in the GraphQL layer. This is critical because GraphQL query result data winds up being serialized as JSON (page-data.json) for each page/query.

You may be better off by simply using a good React-focused markdown renderer, like markdown-to-jsx, which would allow you to provide a React component or function to be used for any given HTML element:

import Markdown from "markdown-to-jsx"

export default ({ data }) => 
  <Markdown
    options={{
      overrides: {
        img: YourImageComponent,
        h1: ({ children, ...props }) => <h1 {...props}>Title: {children}</h1>,
      },
    }}
  >
    {data.page.markdownContent}
  </Markdown>

Upvotes: 2

Related Questions