.astro components
An Astro component is a file with the .astro extension that describes a piece of markup: a site header, a post card, a whole page. It has two parts: the frontmatter with code between the --- lines, and the HTML template below it. The component runs on the server and turns into plain HTML.
A first component
There is no command for creating a component. Create the folder src/components and the file src/components/Header.astro in it:
---
const siteName = "Anna's blog";
---
<header>
<a href="/">{siteName}</a>
</header>The frontmatter declares an ordinary JavaScript variable. In the template its value is inserted with curly braces, just like an expression in a template literal.
Using the component
A component is imported in the frontmatter of another component and written in the template as a capitalized tag. Open src/pages/index.astro:
---
import Header from '../components/Header.astro';
---
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Blog</title>
</head>
<body>
<Header />
<h1>Posts</h1>
</body>
</html>Open http://localhost:4321 and the link "Anna's blog" appears at the top. The tag name matches the name the component was imported under.
Expressions in the template
Any JavaScript expression can go inside curly braces. Lists are rendered with map(), conditions with && or the ternary operator:
---
const posts = ['First post', 'How I learn Astro', 'Notes on CSS'];
const isEmpty = posts.length === 0;
---
<h1>Posts ({posts.length})</h1>
{isEmpty && <p>No posts yet.</p>}
<ul>
{posts.map((title) => <li>{title}</li>)}
</ul>The page shows the heading "Posts (3)" and a list of three items. Text in curly braces is escaped automatically: < and > characters in a string do not become tags.
Differences from HTML and JSX
| What | How in Astro |
|---|---|
| Class attribute | class, as in HTML (not className) |
| Attribute value from a variable | href={url} |
| Several elements without a wrapper | allowed, no root element needed |
| Comment | <!-- --> ends up in the HTML, {/* */} does not |
| Ready HTML string | the set:html={html} directive |
Common mistake
Frontmatter variables are computed once, when the page is built. In the built site, const now = new Date() shows the build time, not the moment a visitor opened the page. For something that changes in the browser you need a client script or an island; for a page recalculated on every request you need on-demand rendering.