The .astro Component Syntax
The frontmatter script block and HTML-like template that make up every .astro component.
អាន 2 នាទី
Every .astro file is a component, whether it's used as a full page or a small reusable piece. Understanding the two-part structure — frontmatter and template — is the foundation for everything else in Astro.
The frontmatter block
The section between the --- fences is called the frontmatter, borrowed from the Markdown convention of metadata at the top of a file. In Astro, it's not metadata — it's real JavaScript/TypeScript that runs on the server (or at build time), before any HTML is produced.
---
import Card from "../components/Card.astro";
const title = "Component Frontmatter";
const items = ["one", "two", "three"];
function shout(text: string) {
return text.toUpperCase();
}
---You can import other components, define variables and functions, and — as later lessons cover — fetch data from an API or the filesystem. Everything here runs in a Node-like server environment. There is no window, no document, and no access to browser APIs, because this code never reaches the browser.
The template
Everything below the closing --- is the template: HTML, plus JavaScript expressions wrapped in curly braces, similar to JSX.
---
const title = "Component Frontmatter";
const items = ["one", "two", "three"];
---
<section>
<h2>{title}</h2>
<ul>
{items.map((item) => (
<li>{item}</li>
))}
</ul>
</section>Curly braces evaluate any JavaScript expression: variables, function calls, ternaries, .map() over arrays. What can't go inside curly braces is statements — no if blocks or for loops directly in the template — which is why conditionals in Astro templates typically use ternaries or &&, the same pattern JSX uses. The next lesson covers this in detail.
No frontmatter required
The frontmatter fences are optional. A component with nothing dynamic can skip them entirely:
<footer>
<p>© 2026 My Site. All rights reserved.</p>
</footer>This is a perfectly valid .astro component — Astro only adds a frontmatter section to the output pipeline if you write one.
Multiple root elements are fine
Unlike JSX, an Astro template doesn't need a single wrapping element. You can return sibling elements directly:
---
const label = "Astro";
---
<h1>{label}</h1>
<p>No wrapping div required.</p>This is a small but telling difference: Astro templates compile to HTML strings, not to a virtual DOM tree that a framework needs to reconcile, so there's no requirement for a single root node the way there is in React.
Taken together, frontmatter plus template is the entire component model in Astro — no class syntax, no hooks, no lifecycle methods. A component is a function that runs once (per request or build) and produces HTML.