Frontmatter & Template
A React component has two logical sections: the function body (where you declare variables, call hooks, and run logic) and the returned JSX (what renders). An Astro component mirrors this split with an explicit fence.
---// frontmatter: JS/TS that runs at build or server time---<!-- template: HTML-first markup rendered to static HTML -->The --- pair is called the component script or frontmatter. Everything between the fences is plain TypeScript/JavaScript. Everything after the closing --- is the template — an HTML superset where you can embed expressions with {...}.
Frontmatter: the component script
Section titled “Frontmatter: the component script”Think of the frontmatter as the top of a React function, minus hooks and event handlers. You can:
- Import other components, utilities, and data files.
- Fetch data with
await(the entire component runs on the server/build). - Destructure props from
Astro.props. - Declare local variables that the template reads.
// Card.jsx (function body = "frontmatter")import { formatDate } from './utils';
export default function Card({ title, date }) { // runs in the browser on every render const formatted = formatDate(date);
return ( <div className="card"> <h2>{title}</h2> <time>{formatted}</time> </div> );}---// Card.astro (frontmatter = component script)import { formatDate } from './utils';
// runs ONCE at build time — never in the browserconst { title, date } = Astro.props;const formatted = formatDate(date);---<div class="card"> <h2>{title}</h2> <time>{formatted}</time></div>The HTML template
Section titled “The HTML template”After the closing --- you write HTML. It is not JSX:
- Use
classnotclassName. - Boolean attributes work the standard HTML way.
- Self-closing tags follow HTML rules (but Astro is lenient — both
<img />and<img>work). - Embed any JavaScript expression with
{expr}.
---
const items = ["Astro", "React", "TypeScript"];
const hero = { title: "Welcome", subtitle: "Zero JS by default" };
---
<html lang="en">
<head><meta charset="utf-8" /><title>{hero.title}</title></head>
<body>
<h1>{hero.title}</h1>
<p>{hero.subtitle}</p>
<ul>
{items.map((item) => <li>{item}</li>)}
</ul>
</body>
</html>