Astro Components Made Simple (Beginner-Friendly!)

WarishWarish
12 min read

Imagine you’re building a LEGO house from scratch.

You begin with a flat baseplate as the foundation. On top of it, you assemble the pieces for the house structure, including walls and roofs. Then, you add the features that make a house functional: windows, doors, and furniture pieces. Finally, you perfect your house with finishing touches, such as the plants by the windows, the picture hanging on the wall, or the little mailbox in the front.

Each LEGO piece has a specific purpose, and when thoughtfully combined, they create a complete house. This approach perfectly mirrors how we build websites with Astro components. They are building blocks for developing efficient websites by breaking down entire web interfaces into manageable, reusable pieces.

LEGO house and web compoinents

This guide is perfect for complete beginners who have a basic understanding of HTML, CSS, and (a bit of) JavaScript—that's all the knowledge you need to get started! By the end, you’ll understand the core concept of an Astro component, from its structure to how to use it. You can use knowledge from here to build your own components and website.

Understanding Astro Components

Astro components are standalone units that handle specific aspects of your website's functionality or appearance. They use the .astro extension and are reusable throughout your site. Each component can be developed, tested, and maintained separately.

You can think of your website as a huge chunk of code. Components allow you to divide it into smaller, manageable sections, such as a header (Header.astro), navigation bar (Navigation.astro), article card (ArticleCard.astro), and footer (Footer.astro). These independent components work together to create a fully functional website.

A website breakdown

Why should you create components? If you're building a simple, single webpage with minimal content, well, components might seem unnecessary. But what if you want to reuse a content card on multiple pages? What if you want to display the same element but have different content and colors? Or, you simply look for a better way to organize your codebase. This is where you need components.

By creating a reusable component, you can:

  • Use it multiple times on different pages.

  • Pass different data to display varying content.

  • Make changes to the entire site by changing just one element.

  • Organize your code logically.

Example: Before & After of Astro Components

To illustrate how Astro components can help with website development, let's create multiple buttons with different labels. We'll use both HTML and component-based approaches.

Before Using Components:

<!-- index.astro -->
<button class="primary-button">Sign Up</button>
<button class="primary-button">Learn More</button>
<button class="primary-button">Contact Us</button>

You have to repeatedly copy and paste the same button element. If you later decide to change the styles or add icons to the buttons, you must do so individually. This can be inefficient and hard to maintain as your site grows or has buttons on multiple pages.

After Using Components:

<!-- Button.astro component -->
<button class="primary-button">{text}</button>

<!-- index.astro -->
<Button text="Sign Up" />
<Button text="Learn More" />
<Button text="Contact Us" />

(Note: I cut the frontmatter for easy differentiation.)

Now, if you want to change the button style, you only modify the Button.astro component once, and all instances update automatically. Plus, notice how much cleaner and more maintainable the code is with components.

Tip: Capitalize your component file names (e.g., Button.astro) to distinguish them from other HTML elements.

How Astro Components Work?

Astro components render into HTML at build time (all pages are generated when you deploy your site) or on demand (when a user visits a specific page). This means that your site's visitors will see pure HTML and CSS with no heavy JavaScript, resulting in faster page loads. (“Zero JavaScript by default“ is one of the Astro’s main features.)

When you need interactive elements on your site, such as buttons or forms, Astro handles this through "client islands." They let you add JavaScript only where needed. You can do this by…

  1. Adding <script> tags within your frontmatter (or “component script,” which we will come back to this later)

  2. Using UI Framework components (e.g., React, Vue, Svelte, etc.)

For dynamic content that changes based on user data or other factors (like user profiles or personalized recommendations), Astro uses "server islands" with server directives. These parts load their content when ready, while the rest of the page loads normally without waiting.

Note: For more information on client islands and server islands, refer to Island architecture in the Astro official documentation.

Astro rendering methods

Astro offers different rendering methods based on content needs.

Ways of Using Astro Components

Remember our LEGO house analogy? Astro websites use a variety of components, much like a LEGO house uses different pieces for different purposes.

  • Baseplate piecesPage Components. These are the foundations of your creation, providing the base structure on which everything else is built.

  • Frame and wall piecesLayout Components. These are the consistent structural elements that give your creation shape and form.

  • Specialized pieces (windows, doors, furniture)Element Components. These reusable pieces add functionality and visual appeal throughout your creation.

Page Components

Astro components can be your entire web pages. These components are located in the src/pages/ directory and use Astro’s file-based routing system. Simply put, the .astro files in this folder automatically map to a corresponding URL path on your website. For example, your index.astro becomes yoursite.com/, or about.astro becomes yoursite.com/about.

Layout Components

Layout components are reusable templates that contain the same structure appearing on multiple pages. One example is BaseLayout.astro, which functions as the foundation for your entire site. It typically includes the common HTML structure (like <head> with metadata), header, navigation bar, and footer.

Element Components

Element components are the reusable parts that make up your website's interface. They live in the src/components/ folder and can be imported into any other Astro component, whether in src/pages, src/layouts, or even in the same src/components directory.

Buttons, like in the above example, are one of these components. Here are more examples:

  • ProductCard.astro is a card component that displays product information. You might use it on your shop page to show multiple products in a grid, in "Related Products" of a product detail page, or in "Featured Products" of your homepage.

  • SocialShareBar.astro is a component with social media sharing buttons. You can import it into your blog posts, product pages, or any content you want visitors to share.

Project Structure with Components

With all components together, your project structure might look like this:

src/
  ├── components/
  │   ├── Button.astro
  │   ├── SocialCard.astro
  │   └── Navigation.astro
  ├── layouts/
  │   ├── BaseLayout.astro
  └── pages/
      ├── index.astro
      └── about.astro

When building your site, you'll typically start with BaseLayout.astro, then create specific layouts for different content types. Next, you'll develop individual components and finally assemble everything in your pages. This approach makes your codebase more maintainable and your development process more efficient.

Question: When Should I Create a Component?

When building your first Astro site, you may face the question, "Should I turn this into a component?" While there are no universal rules to this, here's a practical guide to help you decide.

When to Create ComponentsWhen NOT to Create Components
When you need to reuse the same structure or functionality on multiple pagesWhen the code is specific to a single location and won't be reused elsewhere
When similar elements appear multiple times but with different content (like product cards)When an element appears only once with fixed content
When you need to update multiple instances of an element from a single sourceWhen changes will only affect one instance
When the code is complex enough to benefit from being isolated and maintained separatelyWhen the code is simple and doesn't require separate maintenance

Component Structure Deep Dive

Every Astro component consists of two main parts: the component script and the component template.

Component Script

The component script, also known as the "frontmatter," is wrapped within three dashes (---). This section is where you:

  • Import other Astro components. For example, if you want to add the Button.astro component to your index.astro, you import it with import Button from '../components/Button.astro', then use <Button /> anywhere on your homepage.

  • Import data. Retrieve and process data for your component to display. For instance, if you have product information stored in src/data/products.json, you can import and use this data within your ProductCard.astro to show product details like names, prices, and images.

  • Fetch content from external sources. Fetch data from external APIs, databases, or CMS platforms to display in your component. For example, you might pull blog posts from a headless CMS to populate your blog section.

  • Define variables and functions. Create any variables or functions to reference within your component.

  • Set up component props. Define what properties your component can accept. For example, you might specify that a button component accepts a text label and color. (We'll cover props in detail in the next section!)

---
// Component Script (Frontmatter)


// Import Astro components
import Button from '../components/Button.astro';


// Import data
import { type ProductItem } from "@config/productData.json";


// Fetch content
const response = await fetch("https://randomuser.me/api/");


// Define variables
const title = "Featured Products";
const showFeaturedOnly = true;


// Set up component props
interface Props {
  text: string;
  color?: string;
}

const { text, color = 'blue' } = Astro.props;
---

Component Template

Below the frontmatter (under the closing ---) is the component template. This section contains HTML markup that will be rendered to the page and can include:

  • Regular HTML elements, from basic <div> containers to semantic elements like <header>, <nav>, or <footer>.

  • Astro components that you've imported in the component script.

  • JavaScript expressions wrapped in curly braces {} to add dynamic content.

  • Slot elements (<slot />) that act as placeholders for content from parent components. (We’ll talk about this in “Using Slots” below!)

---
// Component script
---
// Component template

// HTML markup
<article class="product-card">

  // Imported components
  <Button text="Add to Cart" color="primary" />
  <ProductCard />

  // JavaScript expressions
  <img src={productData.image} alt={productData.name} />
  <h3>{productData.name}</h3>

  // Slot element
  <slot />
</article>

Working with Props

Think of props as variables you can pass into your Astro components, similar to how you pass arguments to a function. They can be accessed using Astro.props and allow you to create dynamic components that display or appear differently based on the values you provide.

Simply put, you use Astro Props to pass configuration from a parent component to a child component. A parent component specifies what text, color, and size to show, and a child component responds accordingly.

Props let parent components configure how child components appear and behave.

How to Use Props

Let's revisit our button component example. Suppose you want to create Button.astro (child component) and include it in About.astro (parent conponent), displaying "Contact me" in blue text.

  1. Define props in your child component
---
// Button.astro (child component)

// Define what props your component can accept
interface Props {
  text: string;
  color: string;
}

// Set blue as the default color value.
const { text, color = 'blue' } = Astro.props;
---
  1. Use props in your component template
---
// Button.astro (child component)
interface Props {
  text: string;
  color: string;
}

const { text, color = 'blue' } = Astro.props;
---

<!-- Now use the props in your HTML -->
<button class={`btn ${color}`}>
  {text}
</button>
  1. Implement the component with custom props
// About.astro (parent component)
---
import Button from '../components/Button.astro';
---
<Button text="Contact me" />  // Uses default blue color
<Button text="Click me!" color="red" />

Using Slots

Slots are placeholders that allow you to insert HTML content from another file into your components. The <slot /> tag marks the exact location where that custom content will appear. (Think of it as saying, "put your custom content here!")

Using slot

Slots insert custom content into your components.

How to Use Slots

Let's say you've created a reusable Card component (Card.astro) that you want to use on your About.astro page. You need a flexible way to display different information within the same card structure. Here's how you do so using <slot />:

---
// About.astro
import Card from '../components/Card.astro';
---
<Card>
  <h1>My Info</h1>
  <p>This content goes in the slot</p>
</Card>
---
// Card.astro
---
<div class="card">
  <slot />  <!-- The h1 and p elements appear here -->
</div>

When rendered, the content between the <Card> tags in About.astro replaces the <slot /> in Card.astro. This creates a complete component that combines your reusable card structure with page-specific content.

Note: Astro also supports named slots. To use them, add the name attribute to your slot (<slot name="header" />) and the corresponding slot attribute to the content you want to place there (<h1 slot="header">Title</h1>). This allows for multiple content insertion points in a single component.

Props vs. Slots: When to Use Which?

PropsSlots
Pass data value (strings, numbers, objects)Pass HTML content
Customize how components look and displayInsert content into components
Must be defined in the component scriptJust use <slot /> in the component template
Example: Button text, card title, theme colorsExample: Card body content, layout sections, custom HTML

In summary, use props when you need to customize properties of a component and slots when you need to insert content into specific areas of that component.

Implementing Astro Components: Next Steps

Now that you understand how Astro components work, you're ready to build a more organized website and tackle complex concepts. Just like how LEGO builds from pieces to a full house, here's your roadmap for implementing Astro components:

Here's your roadmap for implementing Astro components in your projects:

  1. Start with basic blocks. Begin with simple components like buttons or cards. A practical approach is to identify repetitive HTML patterns in your existing code and convert them into reusable components.

  2. Create your component library. Organize your components within your project:

  • Place reusable UI components in src/components

  • Store layout templates in src/layouts

  • Keep page components in src/pages

  1. Build complex layouts. Once you're comfortable with basic components, experiment with nesting and combining them to create sophisticated layouts.

Further Reading

Want to learn more about web development? Follow H1Tags blog for more tutorials and knowledge articles. Thank you for reading!

0
Subscribe to my newsletter

Read articles from Warish directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Warish
Warish

I'm Waricha or Warish, a technical writer who combines a love for writing with a passion for technology. I'm happiest when my writings help people understand complex concepts better or solve their problems. As a "workflow nerd," I’m always exploring new tools to improve my workflows.