Astro Starter Template

Component showcase

Components are ready-made parts of a page. Import one into an Astro or MDX file, then add it where you want it to appear.

The example import paths below are for files directly inside src/pages/. Change the path if your file is somewhere else.

Button

Use a Button for an important link or action.

import Button from "../components/Button.astro";

<Button href="/contact">Contact me</Button>

Live example:

Contact me

Add a style with variant and a size with size:

<Button href="/about" variant="outline" size="large">
    Learn more
</Button>
Learn more

Button options

Prop Choices Default
href Any page or website address No address; renders a button.
disabled true or false false
variant primary, secondary, outline, ghost, danger primary
size small, medium, large Looks like medium
iconLeft An icon name No icon
iconRight An icon name No icon

Add an icon like this:

<Button href="https://astro.build" iconRight="external">
    Visit Astro
</Button>
Button links, actions, and extra attributes

When href is present, Button renders a link. Without href, it renders a native button.

Use type="submit" inside a form:

<Button type="submit" iconLeft="approve-check">Save</Button>

The available button types are button, submit, and reset. You can also pass normal attributes such as disabled, name, value, target, rel, aria-*, and class.

An explicit size keeps the button at its natural width. Without one, a parent layout may stretch it.

Callout

Use Callout to give a note, result, warning, or error more context than the surrounding prose.

import Callout from "../components/Callout.astro";

<Callout variant="warning" title="Check before publishing">
    Replace the example site URL and social image with your own.
</Callout>

Live example:

Check before publishing

Replace the example site URL and social image with your own.

Prop Choices Default
variant info, success, warning, danger info
title Any non-empty title The selected variant’s name
class An extra CSS class No extra class

Place the callout content inside the component. It can contain paragraphs, lists, links, and other simple prose.

DescriptionList

Use DescriptionList for a compact set of labels and explanations.

import DescriptionList from "../components/DescriptionList.astro";

<DescriptionList
    eyebrow="Project details"
    items={[
        {
            label: "Framework",
            description: "Astro with optional MDX content.",
        },
        {
            label: "Styling",
            description: "Design tokens and scoped component styles.",
        },
    ]}
/>

Live example:

Project details

  • FrameworkAstro with optional MDX content.
  • StylingDesign tokens and scoped component styles.

Each item requires a non-empty label and description. Add an href to make an individual row a link. The optional eyebrow labels the whole group.

InfoBar

Use InfoBar to make a compact set of facts or metrics easy to scan.

import InfoBar from "../components/InfoBar.astro";

<InfoBar
    items={[
        { label: "Downloads", content: "45.2K" },
        { label: "Weekly users", content: "3,800" },
        { label: "Server status", content: "Online" },
    ]}
/>

Live example:

Downloads
45.2K
Weekly users
3,800
Server status
Online

Each item requires a non-empty label and non-empty string or finite number content. InfoBar automatically fits as many items as its container allows, then wraps the remaining items into evenly filled rows.

Items use a minimum width of 10rem. Override it for a particular bar with the --info-bar-min-item-width custom property:

<InfoBar
    style="--info-bar-min-item-width: 12rem;"
    items={[
        { label: "Plan", content: "Professional" },
        { label: "Renewal", content: "September 30" },
    ]}
/>

Figure

Use Figure when an image, illustration, or video needs a visible caption and optional credit.

import Figure from "../components/Figure.astro";
import { Image } from "astro:assets";
import exampleImage from "../assets/images/example.png";

<Figure
    caption="Traffic moves through Gwanghwamun Square in Seoul."
    credit="Bryan Hogan"
    creditHref="https://bryanhogan.com"
>
    <Image src={exampleImage} alt="" loading="lazy" />
</Figure>

Live example:

Traffic moves through Gwanghwamun Square in Seoul beneath Bugaksan mountain.Credit: Bryan Hogan

caption and the default media slot are required. credit is optional, and creditHref can link that credit to its source. When the caption already describes the image, use an empty alt value to avoid repeating the same text to screen-reader users.

Cards and card grids

Use CardGrid to arrange related Cards. The grid stacks them on small screens.

import Card from "../components/Card.astro";
import CardGrid from "../components/CardGrid.astro";

<CardGrid columns={2}>
    <Card title="Fast" heading="h3" icon="rocket">
        <p>Astro ships less JavaScript by default.</p>
    </Card>
    <Card title="Flexible" heading="h3" icon="setting">
        <p>Add only the features your site needs.</p>
    </Card>
</CardGrid>

Live example:

Fast

Astro ships less JavaScript by default.

Flexible

Add only the features your site needs.

Card also supports media, actions, mediaAspect, and setWidth. CardGrid supports two or three columns and small, large, or full widths.

Hero

A Hero is the large introduction at the top of a page. It includes the page’s main heading, so normally use it only once.

import Hero from "../components/Hero.astro";
import Button from "../components/Button.astro";

<Hero
    heading="Build your first website"
    headingHighlight="with Astro."
    headingId="home-title"
    eyebrow="Simple and flexible"
    description="Start with useful pages, components, and styles."
>
    <Fragment slot="actions">
        <Button href="/about" size="large">Learn more</Button>
    </Fragment>
</Hero>

The required values are:

  • heading is the main heading text.
  • headingId is a unique name that connects the hero to its heading.

headingHighlight, eyebrow, and description are optional. The actions slot is for buttons.

Add an image to the Hero

Use the media slot:

import { Image } from "astro:assets";
import heroImage from "../assets/images/hero.png";

<Hero heading="Welcome" headingId="welcome-title">
    <Image
        slot="media"
        src={heroImage}
        alt="Describe what is shown in the image"
        loading="eager"
    />
</Hero>

The Hero changes to a two-column layout on wide screens when it has media.

Add an animated background to the Hero

To add animation, import AnimatedBackground and wrap the Hero component in it:

import Hero from "../components/Hero.astro";
import AnimatedBackground from "../components/AnimatedBackground.astro";

<AnimatedBackground>
    <Hero
        heading="Build your first website"
        headingId="home-title"
        description="Start with useful pages, components, and styles."
    />
</AnimatedBackground>

The background spans the full page width, with outlined rectangles that float upward and smoothly become circles. Keep any actions and media inside Hero as usual. See src/pages/index.mdx for a complete example.

Animation is optional: use Hero on its own for a plain background. The animation pauses when offscreen or the browser tab is hidden, and is disabled for visitors who prefer reduced motion.

Change the Hero layout

You can set CSS custom properties through style:

<Hero
    heading="A smaller hero"
    headingId="small-hero-title"
    style="--hero-min-height: 45svh; --hero-highlight-color: var(--color-accent-alt-200);"
/>

Other available values include --hero-content-max-width, --hero-media-max-width, --hero-section-gap, --hero-columns, --hero-actions-direction, and --hero-layout-max-width.

Icon

Use Icon to show one of the SVG icons in src/components/Icons.ts.

import Icon from "../components/Icon.astro";

<Icon name="rocket" />

Live example:

The icon sits inline with text, inherits its color, and defaults to 1em so it scales with the surrounding font size. Change its size or color when needed:

<Icon
    name="information"
    label="Information"
    size="var(--icon-size-l)"
    color="var(--color-accent-300)"
/>

For consistent fixed sizes, use the tokens in src/styles/var.css: --icon-size-s (1rem), --icon-size-m (1.25rem), or --icon-size-l (1.5rem). Pass a token through size as shown above; the default 1em follows text size instead.

If nearby text already explains the icon, leave out label. The icon will be hidden from screen readers. Add a short label when the icon has meaning on its own.

Icon options and names
Prop Purpose
name Required name from Icons.ts.
label Accessible text for an icon with meaning.
size A CSS size such as var(--icon-size-l) or 1em. Defaults to 1em.
color A CSS color or design token.
class An extra CSS class.

Open src/components/Icons.ts for the complete list. It includes arrows, carets, common actions, social networks, browsers, hosting providers, and development tools.

SectionTitle

SectionTitle gives page sections a small label and a heading.

import SectionTitle from "../components/SectionTitle.astro";

<SectionTitle
    as="h2"
    eyebrow="What is included"
    title="A useful starting point"
/>

Live example:

Example A consistent section heading

Use as="h2" for a main section below the page title. Use as="h3" for a section inside an h2 section.

SectionTitle IDs and other options
Prop Purpose
eyebrow Required small label above the title.
title Required heading text.
as Required heading level from h1 to h6.
id Optional custom link target.
class Optional extra CSS class.

An ID is normally made from the title. For example, A useful starting point becomes a-useful-starting-point.

Add your own ID when the same title appears more than once:

<SectionTitle
    as="h2"
    id="homepage-features"
    eyebrow="Included"
    title="Features"
/>

The eyebrow and title cannot be empty, and a custom ID cannot contain spaces.