Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

.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

WhatHow in Astro
Class attributeclass, as in HTML (not className)
Attribute value from a variablehref={url}
Several elements without a wrapperallowed, no root element needed
Comment<!-- --> ends up in the HTML, {/* */} does not
Ready HTML stringthe 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.

Thanks for reading!

Donate to the site — we work hard for you.