One File, Two Halves — Script and Template
The `.astro` File
An `.astro` file has two parts — a JavaScript frontmatter that runs at build time, and an HTML template that gets rendered.
What you'll learn
- Recognize the two halves of an `.astro` file
- Understand what runs where
The .astro file is the building block of an Astro site. It looks
like HTML with a JavaScript “preamble” — the script half on top,
the template half below.
The Two Halves
---
// 1. Frontmatter script — runs on the SERVER, at build time
const title = "Hello, Astro";
const now = new Date();
---
<!-- 2. HTML template — what the browser actually receives -->
<html>
<head><title>{title}</title></head>
<body>
<h1>{title}</h1>
<p>Rendered at {now.toLocaleTimeString()}.</p>
</body>
</html> The --- fences mark the boundary. Between them is plain
TypeScript (or JavaScript). After the closing fence is the
template, which can use { ... } to drop values from the script
into the HTML.
What Runs Where
| Code location | When it runs | Where it runs |
|---|---|---|
Frontmatter (--- ... ---) | Build / request time | Node (server) |
Template { expr } | Build / request time | Node (server) |
<script> tag in template | Runtime | The browser |
<script is:inline> | Runtime | The browser, untouched |
| Hydrated framework island | Runtime | The browser (after JS loads) |
The default output is HTML. Browser-side JS only runs when you
explicitly opt in via a <script> tag or a hydrated island.
Top-Level await
The frontmatter is async by default — you can await anywhere:
---
const posts = await fetch("https://api.example.com/posts").then(r => r.json());
---
<ul>
{posts.map(p => <li>{p.title}</li>)}
</ul> That fetch happens at build time (for static pages) or per-request (for server-rendered pages). Either way, the browser never sees the network call — it just gets HTML.
TypeScript Out of the Box
The frontmatter is TS. Types Just Work:
---
interface Props {
title: string;
count?: number;
}
const { title, count = 0 } = Astro.props;
---
<h1>{title}</h1>
<p>Count: {count}</p> A Component IS a File
There’s no export default function. The whole file is the
component. Its props come from Astro.props. Importing it makes it
available as a tag:
---
import UserCard from "../components/UserCard.astro";
---
<UserCard name="Ada" /> What’s Next
The next four lessons zoom in on the parts of an .astro file —
frontmatter, template, expressions, attributes.