DEV Community

Cover image for Passing Markdown components to React or Preact in Astro
Cassidy Williams
Cassidy Williams

Posted on • Updated on • Originally published at cassidoo.co

Passing Markdown components to React or Preact in Astro

I am using Astro and Preact (which has the same API as React) for a project. I ran into a issue recently where I wanted to pass a Markdown component to the Preact side of the project, and it wasn't working the way I expected.

First of all, I tried importing it into my Preact file at the top:

// Preact Component
import Blog from './Blog.md'

function PreactComponent() {
    return (
        <div>
            <Blog />
        </div>
    )
}

Enter fullscreen mode Exit fullscreen mode

But sadly, that didn't work! Doing that type of import is only possible in .astro components, even though Astro has support for Preact and React (amongst other things) out of the box.

I realized (after actually reading the documentation, shocking) that you can't pass Markdown directly to non-Astro components.

So, I thought it might be useful to import the Markdown into a parent Astro component, and then pass that into my Preact component from there.

// Parent Astro Component
---
import Blog from './Blog.md';
---

<PreactComponent
  blog={(<Blog />)}
  client:visible
/>
Enter fullscreen mode Exit fullscreen mode

This was close, but no cigar. Turns out, you can't pass JSX as props to framework components.

Entering... slots!

I learned about Named Slots in Astro and that changed the game! This is a concept that is pretty common in the Vue and Svelte communities, but I admit as a React person I hadn't really tried them before.

So, what I had to do was define a slot in my Astro parent component:

// Parent Astro Component
---
import Blog from './Blog.md';
---

<PreactComponent>
    <Blog slot="blog" />
</DemoContent>
Enter fullscreen mode Exit fullscreen mode

...and then from there, treat the blog slot as a prop on the Preact side!

// Preact Component

function PreactComponent({ blog }) {
    return (
        <div>
            {blog}
        </div>
    )
}
Enter fullscreen mode Exit fullscreen mode

And voilà, I now can render Markdown in a React/Preact component in Astro.

This is particularly useful for me because I have some non-technical folks giving me Markdown files to share on a website (with some state-driven logic determining what copy should be shown when). Now that I'm able to pass in the Markdown this way, I can have a separate Markdown file folder for them to work with, without messing with the logic of the website. Woo hoo!

Special thanks to Ben Holmes for helping me out with this, as well as Alex and Charlie! Ben made an awesome little demo on StackBlitz to illustrate the issue, and here's a related Stack Overflow question as well if you find this helpful and want to upvote!

Top comments (2)

Collapse
 
vincenthall profile image
Jack

Solid pointer. Working on my own little blog in Astro right now and this comes just in time to save me some frustration.

Collapse
 
tobecci profile image
Tochukwu Ojinaka

nice and easy to understand 🤲