Components and layouts
Use template expressions
Insert values, choose markup, and render arrays with JavaScript expressions.
Braces insert JavaScript into the template. Anything inside {} runs while Astro renders the component, and the result becomes HTML.
The most common case is printing a value:
---
const title = 'Astro notes'
---
<h1>{title}</h1>
Conditionals
Use && to render something only when a condition is true:
{featured && <strong>Featured</strong>}
If featured is false, nothing is emitted. Not even an empty tag.
Loops
Call map() on an array and return markup for each item:
<ul>
{items.map(item => <li>{item.name}</li>)}
</ul>
With three items you get three li elements in the page source. The array itself never reaches the browser.
Keep logic in the script
Expressions are for choosing and inserting. When the logic grows, move it above the fence and give it a name:
---
const visibleItems = items.filter(item => !item.draft)
---
{visibleItems.length > 0 ? (
<ul>{visibleItems.map(item => <li>{item.name}</li>)}</ul>
) : (
<p>No items yet.</p>
)}
Now the template reads like a description of the output, and the filtering has a name you can search for.
This is not JSX
Astro looks like JSX but follows HTML more closely. You write class, not className. You can return several top-level elements without wrapping them. Comments use the normal <!-- --> syntax.
One more difference matters a lot. These expressions run once, at render time. If featured changes later in a browser script, this block does not rerender. Astro templates describe HTML. They don’t watch state. That’s the job of a browser script or a hydrated island, which we see later in the course.
Escaping
Values inserted with {value} are escaped. If title contains <script>, the page shows the literal text and the browser does not run it. This is the right default for anything that comes from users or external APIs.
Astro does have a way to insert raw HTML, the set:html directive. Treat it as the exception. Use it only for HTML you trust, like content you rendered from your own Markdown.
Render a page with a conditional and a loop, then view the source. Every branch and every iteration should map to a piece of static HTML. If you can’t connect them, the template is doing too much.
Lesson completed