Passing Markdown Components to React or Propagate in Astro

I’m using Astro and Preact (which has the same API as React) for a project. I recently ran into an issue where I wanted to pass a markdown component to the PreAct side of the project, and it wasn’t working as I expected.

First, I tried to import this 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 it didn’t work! That type of import is possible only in .astro Components, even though Astro has support for PreAct and React (among other things) out of the box.

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

So, I thought it might be useful to import Markdown into a native 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

It was close, but the cigar was not. Turns out, you can’t pass JSX props for the components of the framework.

Entering… Slots!

I learned about the named slot in Astro and it changed the game! It’s a concept that’s very common in the Vue and Svelte communities, but I’ll admit as a feedback person that I’ve never actually 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 treat from there blog Preact the slot on the side as a prop!

// Preact Component

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

exit fullscreen mode

And voila, I can now render markdown in Astro in a react/preact component.

This is especially useful to me because I have some non-technical people giving me markdown files to share on a website (some state-driven logic determines which copy should be shown when). Now that I’m able to pass in markdown like this, I can have a separate markdown file folder to work with them, without messing with the logic of the website. Woo hoo!

special thanks to ben holmes to help me with this, as well alex And Charlie, Ben made a very short demo on Stackblitz to clarify the issue, and there’s also a related Stack Overflow question here if you find it helpful and want to upvote!

Leave a Comment