Create Reusable Components in Astro
In web development, repeating code is a common problem. You might find yourself writing the same HTML structure or applying the same styles multiple times. Astro offers a powerful solution: reusable components. This guide will show you how to take existing code, turn it into a reusable component, and use it throughout your Astro website. This makes your code cleaner, easier to manage, and saves you time.
What You’ll Learn
This tutorial will guide you through the process of creating your first Astro component. You will learn how to:
- Create a new Astro component file.
- Move existing HTML and styles into the component.
- Pass data into components using props.
- Define expected props using TypeScript for better type checking and autocompletion.
Prerequisites
- Basic understanding of HTML and CSS.
- An existing Astro project with some content (like a list of items).
Step 1: Create a New Component Folder
First, you need a place to store your components. A common practice is to create a dedicated folder for them. Inside your project’s src directory, create a new folder named components.
This keeps your project organized, separating pages from reusable UI elements.
Step 2: Create the Component File
Inside the new components folder, create a new file for your component. Let’s call it BookCard.astro. The .astro file extension tells Astro that this is an Astro component, not a regular page.
Step 3: Move Your Template Code
Now, let’s move the HTML structure for a single item (in this case, a book card) into your new component. Go to the page where you are currently displaying these items. Select and cut the HTML block that represents one book card.
For example, if you have a list of books and each book is displayed using a specific card layout, cut that entire card layout code.
Step 4: Paste Code into the Component
Open your BookCard.astro file. At the very top, add the front matter by typing two sets of three dashes: ---. Below the front matter, paste the HTML code you just cut from your page.
Your BookCard.astro file should now look something like this:
---
---
Book Title Here
Author Name Here
Step 5: Use the New Component on Your Page
Return to the page where you originally cut the code. Replace the old book card HTML with your new component. Astro will usually prompt you to import the component automatically. If it doesn’t, you’ll need to add an import statement at the top of your page file.
The line to add would look like this:
import BookCard from '../components/BookCard.astro';Then, in your page’s template, where you used to have the card’s HTML, you’ll now use your component like an HTML tag:
<BookCard />If you are rendering a list of items, you’ll place the component inside your loop:
{books.map(book => (
<BookCard /
))}
Step 6: Pass Data Using Props
You’ll notice that your component doesn’t display any data yet. This is because the component doesn’t know about the specific book’s title or author. To fix this, you need to pass data into the component using props (short for properties).
Go back to your page file where you are using the <BookCard /> tag. Inside the loop, add a book prop to the component tag and assign the current book item to it:
{
books.map(book => (
<BookCard book={book} /
))
}
The book={book} part tells Astro to send the current book object from your loop to the BookCard component, where it will be available as a prop named book.
Step 7: Receive and Use Props in the Component
Now, go back to your BookCard.astro file. To access the props passed to your component, you need to destructure them from Astro.props within the front matter.
Add the following lines inside the --- front matter:
const { book } = Astro.props;This line makes the book object available within your component’s script and template. Now, update the template in BookCard.astro to use the data from the book prop:
---
const { book } = Astro.props;
---
{book.title}
By {book.author}
With this change, your component will now display the correct title and author for each book.
Step 8: Move Component Styles
Components often have their own styles. To keep things organized, move the styles associated with your book card from the page file into the BookCard.astro component.
First, cut the relevant CSS styles from your page file. Then, in BookCard.astro, add a <style> tag within the front matter (or below it, depending on your preference) and paste your styles inside it.
---
const { book } = Astro.props;
---
.card {
border: 1px solid #ccc;
padding: 1rem;
margin: 1rem;
border-radius: 8px;
}
.card h3 {
margin-top: 0;
color: #333;
}
.card p {
color: #666;
}
{book.title}
By {book.author}
Astro scopes these styles to the component, so they won’t accidentally affect other parts of your website.
Step 9: Define Props with TypeScript (Recommended)
To make your components more robust and prevent errors, you can define the expected shape of your props using TypeScript. This provides type checking and helpful autocompletion.
In BookCard.astro, inside the front matter, define an interface for your props:
interface Props {
book: {
title: string;
author: string;
};
}
const { book } = Astro.props;
Now, Astro knows that the book prop must be an object containing a title (string) and an author (string). If you try to pass a prop with a different structure or a missing property, Astro will show an error.
Expert Note: This TypeScript interface also unlocks autocompletion. When you type book. in your template, your code editor will show you the available properties (title and author), reducing typos and speeding up development.
Conclusion
Congratulations! You’ve successfully created a reusable Astro component. By breaking down your UI into smaller, manageable components and using props to pass data, you make your website’s codebase more organized, maintainable, and efficient. This modular approach is fundamental to building complex web applications with Astro.
Source: Astro Crash Course #7 – Reusable Components (YouTube)