Skip to content

Props

In React, props arrive as the first argument of the component function. In Astro, props arrive via the global Astro.props object, which you destructure in the frontmatter — the same destructuring syntax you already know.

React
// Button.jsx
export default function Button({ label, variant = "primary" }) {
return (
<button className={`btn btn--${variant}`}>
{label}
</button>
);
}
// Usage:
// <Button label="Save" />
// <Button label="Delete" variant="danger" />
Astro
---
// Button.astro
const { label, variant = "primary" } = Astro.props;
---
<button class={`btn btn--${variant}`}>
{label}
</button>
<!-- Usage:
<Button label="Save" />
<Button label="Delete" variant="danger" />
-->

Two things to notice:

  1. Astro.props is the Astro equivalent of the React props object — destructure from it exactly as you would from a function parameter.
  2. Default values work with standard JavaScript destructuring defaults (= "primary").

Astro components support TypeScript natively. Declare an interface Props (or type Props) in the frontmatter and the compiler enforces it at build time.

React
// Card.tsx
interface Props {
title: string;
description?: string;
href: string;
}
export default function Card({ title, description = "", href }: Props) {
return (
<a href={href} className="card">
<h2>{title}</h2>
{description && <p>{description}</p>}
</a>
);
}
Astro
---
// Card.astro
interface Props {
title: string;
description?: string;
href: string;
}
const { title, description = "", href } = Astro.props;
---
<a href={href} class="card">
<h2>{title}</h2>
{description && <p>{description}</p>}
</a>

The interface Props declaration is the idiomatic Astro pattern. Astro’s language server reads it to power editor autocomplete when you use the component.

Astro
---
interface Props {
  name: string;
  role?: string;
  color?: string;
}

const { name, role = "Developer", color = "#6366f1" } = Astro.props;
---
<html lang="en">
  <head><meta charset="utf-8" /><title>Props demo</title></head>
  <body style="font-family:sans-serif;padding:2rem">
    <div style={`border-left:4px solid ${color};padding-left:1rem`}>
      <h1>{name}</h1>
      <p style="color:#888">{role}</p>
    </div>
  </body>
</html>
How do you access props inside an Astro component's frontmatter?
How do you set a default value for an optional prop in Astro?
What is the idiomatic way to add TypeScript types to Astro component props?