Astro the web framework for static sites

Astro the web framework for static sites

Astro is a modern framework, simple and powerful, that provides an excellent developer experience.


Introduction

Astro is an open source framework created by Fred Schott and Nate Moore. Whose focus is to facilitate the creation of static sites, without compromising the development experience and reusing knowledge from other frameworks.

Astro renders your entire site to static HTML during the build. The result is a fully static website with all JavaScript removed from the final page. No monolithic JavaScript application required, just static HTML that loads as fast as possible in the browser regardless of how many UI components you used to generate it. (Fred Schott and Nate Moore, 2021)

Component Islands

It is a Frontend architecture that consists of rendering html on the server (SSR) and pre-defining scopes (Islands), to inject JavaScript. This is interesting because today hydration, which is this process of making the HTML generated on the server interactive, is extremely costly and happens for the full page.

Astro Islands (aka Component Islands) are a pattern of web architecture pioneered by Astro. The idea of “islands architecture” was first coined by Etsy’s frontend architect Katie Sylor-Miller in 2019, n 2019, and expanded on in this post by Preact creator Jason Miller.

Islands come as a solution for performing partial hydration. And it basically runs by setting directives on the components to declare them as interactive.

See below a modest example where I am using a React component to change the button color, they are all the same component, but only one of them is being hydrated:

Syntax

To achieve this result, as stated above, Astro uses directives, but this is not the only innovation proposed. Following the goal of static frameworks like Gatsby, it provides a way to enable static site generation (SSG) and makes this introducing a new syntax.

Basically it’s a combination of html/mdx/vue/svelte with a dash of PHP. Everything that happens between the triple slash ”---” only happens at build time. This allows for a clear distinction between client and server by delegating, what in a SPA would run on the client, to the server.

Running expressions

---
import x from 'x';
const y = x();
---
<div>
{y}
</div>

Using the file system

---
import { Post } from '../components/Post.astro';
const posts = await Astro.glob('../pages/**/posts/**/*.mdx');
---
<div>
{posts.map((post) => <Post {...post} />)}
</div>

Fetching a API

---
const resposta = await fetch('https://cms/api/posts');
const posts = await resposta.json();
---
<div>
{posts.map((post) => <Post {...post} />)}
</div>

Componentization

Layouts

In addition to the triple slash, Astro components allow the creation of layouts with html, which in React for example requires the use of libs such as react-helmet:

<html lang="pt-BR">
<head>
<meta charset="utf-8" />
<meta
content="width=device-width,initial-scale=1,shrink-to-fit=no,viewport-fit=cover"
name="viewport"
/>
</head>
<body>
<slot />
</body>
</html>

Layouts can be reused both within other components and within Markdown files:

---
layout: "./Layout.astro"
---

Styling

Like Svelte and Vue, Astro allows styling, from either scoped or global, direct into components.

<button class="button">Button</button>
<style>
.button {
cursor: pointer;
}
</style>
<style is:global>
* {
box-sizing: border-box;
}
</style>

Props

It wouldn’t be a component if there were no way to receive and require props. Astro components use the props attribute of the Astro variable to access prop values.

---
export interface Props {
name: string;
msg?: string;
}
const { msg = 'Olá', name } = Astro.props;
---
<h2>{msg}, {name}!</h2>

UI agnostic

But you can say “I don’t want to redo all my components” and that’s where Astro shines. It allows you to add integrations with multiple frameworks like:

  • React
  • Vue
  • Svelte
  • Solid
  • Preact

And thanks to the component islands architecture, you can choose whether it is an interactive component or not via template directives.

---
import { DemoButton } from './DemoButton';
---
<section class="islands-scheme">
<header><DemoButton /></header>
<aside><DemoButton /></aside>
<main><DemoButton client:idle /></main>
<footer><DemoButton /></footer>
</section>

Development Experience

This site was built using Astro, and it’s amazing how simple it was to get started. It has a familiar config, built on top of that of vitejs, and it was for the most part, just looking for the integrations I wanted and componentizing.

I only had difficulty with the setup of mermaidjs, but because the syntax of Astro components is valid html I managed to make a functional solution, but it would be interesting to have this support with the markdown same as github/gitlab, maybe with a static generation of the svg.

Update I was able to achieve this using an Astro component with mermaid-parse.
(20/10/2022)

But the overall experience was excellent and the proposed solutions for file system management and execution speed made Gatsby look pretty dated and over engineered.