Components and layouts

The anatomy of an Astro component

Separate render-time logic from the template and understand where each part executes.

An .astro file has two parts. JavaScript that runs while Astro renders, and an HTML template that uses its results. Everything else in Astro builds on this split, so let’s look at it closely.

Here is the smallest useful component:

---
const name = 'Ada'
const greeting = name.toUpperCase()
---

<h2>Hello {greeting}</h2>

The component script

The part between the --- fences is the component script. It runs when Astro renders the component. For a static page that means during npm run build. For an on-demand page it means on the server, when a request comes in.

You can do anything you’d do in a Node.js module here. Import files, read props, fetch data, run calculations. It’s plain JavaScript, or TypeScript.

None of this code is sent to the browser. The visitor gets the result, never the recipe.

The template

Below the fence is the template. It looks like HTML because it is HTML, with expressions in braces.

{greeting} is evaluated once, during the render, and replaced with its value. View the page source and you find <h2>Hello ADA</h2>. No name, no toUpperCase(), no JavaScript.

Three places code can run

This is the mental model to keep:

  • code between the fences prepares the document, on the server or in the build
  • expressions in the template decide which HTML is emitted, at the same time
  • a <script> tag in the template runs later, in the visitor’s browser

The first two happen together, once. The third happens on every page load, on the visitor’s machine. Most Astro bugs I see come from mixing these up, like expecting a variable from the component script to update when the user clicks something.

See it for yourself

Add two logs to the component:

---
console.log('rendering')
---

<h2>Hello</h2>

<script>
  console.log('in the browser')
</script>

Reload the page. The first message appears in the terminal where the dev server runs. The second appears in the browser DevTools console. Two runtimes, two consoles.

Try this on the astro-notes project and keep the two consoles in mind for the rest of the course. Whenever something doesn’t behave as you expect, ask which side it ran on.

Lesson completed