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>
)
}
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
/>
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>
...and then from there, treat the blog
slot as a prop on the Preact side!
// Preact Component
function PreactComponent({ blog }) {
return (
<div>
{blog}
</div>
)
}
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)
Solid pointer. Working on my own little blog in Astro right now and this comes just in time to save me some frustration.
nice and easy to understand 🤲