Pages and routing

Write an Astro page

Combine a server-side component script with the HTML template it renders.

An Astro page is a component that lives under src/pages/ and answers a URL with a full HTML document. Like every Astro component, it has two parts: a component script and a template.

Here is a complete about page:

---
import SiteHeader from '../components/SiteHeader.astro'

const title = 'About'
---

<html lang="en">
  <head>
    <title>{title}</title>
  </head>
  <body>
    <SiteHeader />
    <main>
      <h1>{title}</h1>
    </main>
  </body>
</html>

The component script

The part between the two --- lines is the component script. People also call it the frontmatter, because it looks like Markdown frontmatter.

It runs while Astro renders the page. You can import components, read props, load data, and compute values. Then Astro throws it away. Nothing you write there reaches the browser.

That makes it the right place for work you’d never ship to a client. Reading files, calling an API with a private key, preparing data.

The template

Everything below the fence is the template. It describes the HTML output.

Expressions in braces, like {title}, are evaluated during rendering. The result is plain HTML. The visitor gets <h1>About</h1>, not a variable.

What makes a page a page

A regular component produces a fragment. A button, a card, a header. A page owns the whole document. It emits <html>, <head>, and <body> itself, because it’s responsible for the full response to its URL.

Once a few pages repeat the same shell, you pull it out into a layout. We’ll do that in the components module.

It’s not reactive

This is the part that surprises people coming from React or Vue. The title variable is dynamic at build time, or at request time. It is not dynamic in the browser.

The component script runs once per render, on the server side. Change a variable later in client-side code and nothing rerenders. There is no live component instance in the browser.

If you need behavior in the browser, add a normal <script> tag, or hydrate a framework component. Keep the server-only work in the component script.

Try this: open /about/ and view the page source. Search for SiteHeader, const title, and import. None of them are there. Only the rendered HTML remains, with the header already expanded into its markup.

Lesson completed