4

Passing Markdown components to React or Preact in Astro

 1 year ago
source link: https://dev.to/cassidoo/passing-markdown-components-to-react-or-preact-in-astro-31ml
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Cover image for Passing Markdown components to React or Preact in Astro

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>
    )
}

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!


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK