Using Vue Components inside Astro
Previously, we learned how to create a blog from scratch. So far, we didn’t use any components in our code. Here, I will show how to create and use Vue components inside Astro files.
Initializing the project
To simplify bootstrapping, let’s use a “Blog” template. You can browse available Astro templates here.
mkdir astro-blog
cd astro-blog
npm init astro -- --template blog
npm install
npm install @astrojs/vue vue
Enabling Vue support
Before we start, we need to enable Vue rendering. In your Astro config (astro.config.mjs
), replace an existing renderer with a Vue one:
import vue from '@astrojs/vue';
import { defineConfig } from 'astro/config';
export default defineConfig({
integrations: [vue()],
});
You don’t need to install the @astrojs/renderer-vue
package, it will be bundled with Astro by default.
Creating a Vue component
You can create Vue components in Astro the same way as you do in normal Vue apps. You can use Options API, Composition API, or even <script setup>
.
For the purpose of this guide, we will create an info banner component. Create a Banner.vue
file inside src/components
with the following:
<template>
<div>{{ message }}</div>
</template>
<script
setup
lang="ts"
>
defineProps({
message: {
type: String,
required: true,
},
});
</script>
<style scoped>
div {
padding: 8px;
border: 1px solid #aaa;
border-radius: 4px;
background: #eee;
}
</style>
Using Vue components in Astro files
Let’s now see our component in action. Open src/pages/index.astro
to import the component:
---
// Other imports
import Banner from '../components/Banner.vue';
---
And then use it inside the page template:
---
// Frontmatter script
---
<!-- Rest of the template -->
<Banner message="Hello, Vue!" />
You can also use JS expressions when passing prop values:
<Banner message={`2 + 3 is ${2 + 3}`} />
This way, you can use Vue components inside any Astro file. The other way, unfortunately, is not possible: you can’t use Astro components inside the Vue codebase.
Using Vue components in Markdown files
To use Vue components, you will need to use MDX insted of Markdown. See this guide for more information.
Change src/pages/posts/index.md
file extension to an MDX document (index.mdx
) and open it to import the Banner component:
---
// Frontmatter
---
import Banner from '../../components/Banner.vue';
;
And use it:
---
// Frontmatter
---
<!-- Page content -->
<Banner message="Hello, Vue in Markdown!" />
Building a site with Vue components
Depending on whether your component is static or dynamic, the site build will either include JS or not. In our example, the banner component is static. It doesn’t include any interactive parts, so the output will not include any JS. If we would create an interactive component (e.g. a counter), the output will include the necessary script to run the interactive parts of that component. In any case, the Vue compiler code will not be included.