Passing Markdown components to React or Preact in Astro
Tags: astro, preact, react, markdown
Published: 2022-10-26 21:51:23

---
title: Passing Markdown components to React or Preact in Astro
published: true
description: When you want to pass Markdown components to a non-Astro component (while using Astro itself), you need slots!
tags: astro, preact, react, markdown
cover_image: https://images.unsplash.com/photo-1614612554307-dad4df73f17d?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1770&q=80
canonical_url: https://cassidoo.co/post/md-to-react-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:

```jsx
// 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](https://docs.astro.build/en/guides/markdown-content/#importing-markdown), 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.

```jsx
// 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](https://docs.astro.build/en/core-concepts/astro-components/#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:

```jsx
// 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!

```jsx
// 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](https://twitter.com/BHolmesDev) for helping me out with this, as well as [Alex](https://twitter.com/fimion) and [Charlie](https://twitter.com/cdvillard)! Ben made [an awesome little demo on StackBlitz](https://stackblitz.com/edit/github-sm3kss?file=src/pages/index.astro) to illustrate the issue, and here's [a related Stack Overflow question as well](https://stackoverflow.com/q/74214220/1950503) if you find this helpful and want to upvote!