Destiner's notes

Using Components in Markdown with Astro

14 February 2022

Astro makes it possible to write components using any frontend framework and then use those components inside Markdown pages. Let’s try it.

Astro component

First, let’s create an Astro component:

---
const { message } = Astro.props;
---

<div>{message}</div>

<style>
  div {
    border: 1px solid #999;
    padding: 8px;
  }
</style>

Now we can use that component inside a Markdown page via setup syntax:

---
setup: |
  import Banner from '../component/banner.astro';
---

<Banner message="Some text" />

Frontend framework component

We can also use a frontend framework to write components. Here’s an example using Vue:

<template>
  <div>{{ message }}</div>
</template>

<script setup lang="ts">
  defineProps({
    message: {
      type: String,
      required: true,
    },
  });
</script>

<style scoped>
  div {
    border: 1px solid #999;
    padding: 8px;
  }
</style>

We can use this component the same way as we did for an Astro component:

---
setup: |
  import Banner from '../component/Banner.vue';
---

<Banner message="Some text" />

List/object component prop

Let’s say you have a component that takes a list of elements:

---
const { items } = Astro.props;
---

<div class="list">
  {items.map((item) => <div class="item">{item}</div>)}
</div>

It might be tricky to pass an array to a component inside a Markdown page. You can use the frontmatter to store it:

---
setup: |
  import List from '../component/list.astro';
list: ['Item 1', 'Item 2']
---

<List items={frontmatter.list} />