Astro Components

When you create an Astro project, you’ll see some files ending with the .astro extension.

Let’s take a look at one.

Let’s pick the one shipped in the Minimal template:

---
---

<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="icon" type="image/x-icon" href="/favicon.ico" />
    <meta name="viewport" content="width=device-width" />
    <title>Welcome to Astro</title>
  </head>

  <body>
    <h1>Welcome to <a href="https://astro.build/">Astro</a></h1>
  </body>
</html>

The component is basically HTML, except there are two --- lines at the top. That’s the frontmatter. You might be familiar with this concept from Markdown files, for example I use it in this post in Hugo to set the page title, and the post date.

Note that you could as well omit the frontmatter if it’s empty, and just start the component with an HTML tag. In this case it’s there because this is the default Astro example.

But the interesting thing in Astro is that it can contain JavaScript (or TypeScript if you prefer).

Note that the first example above contained the html, head and body tags because that was a page component, a special kind of component that’s responsible of responding to a route (and lives in src/pages).

Inside src/pages you can also put .md files, and they will be considered markdown pages. Astro will render them as plain HTML unless you set a layout. We’ll see what this means in another post.

Components can be much simpler, like you see for example in this demonstration of how to define variables in the frontmatter using JavaScript (or TypeScript) and we use them in the HTML in a JSX-like syntax:

---
const name = 'Flavio'
---

<p>{name}</p>

This JavaScript code runs at build time, not in the browser. If you want to add JavaScript that’s ran in the browser, you can add a script tag in the page:

---
const name = 'Flavio'
---

<p>{name}</p>
<script>
  alert('test')
</script>

And you can do much more than just defining variables.

You can use the frontmatter to import components or libraries. You can fetch data. You can define variables that will then be available in the HTML.

In any component you can define scoped CSS using the style tag:

---
const name = 'Flavio'
---

<p>{name}</p>
<style>
  p {
    color: red;
  }
</style>

When you define a component in the src/components folder, it’s then available anywhere in your Astro components, you just need to import it and you embed it:

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

<Test />

It’s not really JSX, but it’s actually an improvement.

For example, to modify the head part of a page component, just add a head tag. You can comment using normal HTML comments, <!-- --> instead of {/* */}. You can use HTML special characters. And HTML attributes don’t need to be camelCased. No more className=.

Small things, but yeah. It makes it simpler.

Astro provides some built-in components. For example Markdown if you want to embed some Markdown in your components:

---
import { Markdown } from 'astro/components';
---

<Markdown> # test </Markdown>

You have Code to embed code that’s syntax highlighted directly at build time.

For the same thing there’s also Prism if you want to use Prism (the library I use here on the blog), which includes client-side JavaScript.

And Debug which you can use to debug your frontmatter code in the client-side by printing the content of the variable inside the page:

---
import Debug from 'astro/debug';
const name = 'Flavio'
---

<Debug {name} />

Check out my Web Development Bootcamp. Next cohort is in April 2022, join the waiting list!