NodeJS Video Tutorial: Discovering Astro

Welcome to this video where I invite you to discover Astro, a site generator, which has just been upgraded to version 1.0 recently.

00:00 Discovery of Astro
04:21 Markdown support
05:12 Static rendering
06:53 The interactive island system
18:07 Other features
19:05 Server side rendering
25:05 My review

Another JavaScript tool!

Even though there are already many site generators, Astro offers an interesting approach that makes it interesting in this already loaded ecosystem.

A focus on HTML rendering

The first particular point, compared to solutions like NextJS, is that it focuses on static HTML rendering and the pages will not use JavaScript by default. These HTML pages can be generated using files .astromarkdown files or using libraries like React, Svelte, Vue or others.
The files .astro allow you to insert JavaScript at the beginning of the file to perform logic (if needed) to retrieve data at compile time.

---
const projects = (await Astro.glob('./project/**/*.md'))
    .filter(({ frontmatter }) => !!frontmatter.publishDate)
    .sort(
        (a, b) =>
            new Date(b.frontmatter.publishDate).valueOf() - new Date(a.frontmatter.publishDate).valueOf()
    );
---

<section>
    {projects.map((project) => <PortfolioPreview project={project} />)}
</section>

It is even possible to use fetch if you want to retrieve data from an API during compilation

---
const todos = await fetch('https://jsonplaceholder.typicode.com/todos?_limit=10').then(r => r.json())
---
<ul>
    {todos.map(
</ul>

Apart from this particularity, we find almost the same functionalities as with other tools, such as the possibility of using dynamic routes or a paging system.

Interactive islands

Astro’s main selling point is its island system that allows certain on-page elements to be made interactive with client-side hydration.

<Nav />
<SiteHeader />
<main>
    <Counter client:load>
</main>

The use of the client directive indicates that the component must also be executed on the client side and Astro will take care of delivering the JavaScript necessary for the component to work on the pages where it is used. It is also possible to only load the components under certain conditions depending on the importance of the element.

<BuyButton client:load /> <!-- Le composant se charge au chargement de la page -->
<BuyButton client:idle /> <!-- Le composant se charge lorsque le navigateur n'est plus occupé -->
<BuyButton client:visible /> <!-- Le composant se charge lorsque l'élément devient visible à l'écran -->
<BuyButton client:media="(max-width: 50em)" /> <!-- Le composant se charge en fonction d'une media query -->
<BuyButton client:only /> <!-- Le composant se charge seulement côté client -->

This approach makes it possible to limit the use of JavaScript to the elements that strictly need it rather than going through a complete hydration of the page as other frameworks can do.

Server-side rendering

It is also possible to opt for server-side rendering which will allow you in this case to access the information of the request and to respond according to what you receive. The system then relies on the same API as the web with the objects Request and Response.

export async function post ({request}) {
    const data = await request.json();
    return new Response(JSON.stringify({
        success: `Bonjour ${data.firstname} ${data.lastname}`
    }), {
        status: 200,
        headers: {
            'Content-Type':'application/json'
        }
    })
}

You can then choose several adapters depending on the environment on which you want to use your site. For example, in the case of NodeJS it will generate a file entry.mjs that you can include in your server code.

import http from 'http';
import { handler as ssrHandler } from './dist/server/entry.mjs';

http.createServer(function(req, res) {
  ssrHandler(req, res, err => {
    if(err) {
      res.writeHead(500);
      res.end(err.toString());
    } else {
      // Serve your static assets here maybe?
      // 404?
      res.writeHead(404);
      res.end();
    }
  });
}).listen(8080);

For what use?

As you will have understood, Astro returns to a more traditional approach in the creation of web pages with rendering focused on HTML and navigation managed by the browser rather than “all JavaScript”. This approach will be quite suitable for cases of showcase sites, portfolios, small blogs and documentations but will not be suitable if you need client-side navigation or if you are creating a site in “application” format.