Real HTML With JavaScript-Powered Holes
The HTML Template
Below the second `---` fence is the template. It's HTML with `{ ... }` for JavaScript expressions — but it's still real HTML.
What you'll learn
- Read and write the template half
- Use expressions inside markup
- Recognize the differences from JSX
The template half is HTML you can drop JavaScript expressions into. It looks a lot like JSX, but with a few key differences — because the output really is HTML.
The Shape
---
const title = "Hello";
---
<html>
<head>
<title>{title}</title>
</head>
<body>
<h1>{title}</h1>
</body>
</html> Differences From JSX
| Concern | Astro | JSX |
|---|---|---|
| Attribute names | HTML names (class, for) | Renamed (className, htmlFor) |
| Comments | <!-- HTML comment --> | {/* JSX comment */} |
| Style attribute | string or object | object only |
| Multiple roots | OK at top level | Must wrap in fragment |
{ } expressions | Yes | Yes |
You can write <label for="x">, not htmlFor. You can write
<div class="card">, not className. Astro keeps HTML’s spelling.
Multiple Top-Level Elements
Unlike JSX, an Astro template’s top level doesn’t need a wrapping element:
---
---
<h1>Title</h1>
<p>Body</p> (Inside a component used in a JSX-style context — e.g., a React island — you’d still need a wrapper.)
Comments
Either kind works:
<!-- HTML comment — appears in the output -->
{/* JSX-style comment — stripped at build */} Style Attribute
Strings and objects both work:
<div style="color: red; font-size: 14px;">A</div>
<div style={{ color: "red", fontSize: "14px" }}>B</div> JSX is object-only. Astro accepts either.
Up Next
The expressions inside { ... } — what’s allowed and the idioms.