Le développement web a parcouru un long chemin depuis les premiers jours des sites web personnels statiques d’une seule page. Aujourd’hui, nous disposons d’une pléthore de langages, de frameworks et de systèmes de gestion de contenu différents qui ont été créés pour répondre à tous les créneaux possibles et imaginables.

C’est là qu’intervient Astro, l’un des derniers-nés des frameworks JavaScript.

Créé par Fred K. Schott et un groupe d’autres contributeurs, Astro est rapidement devenu l’un des favoris de la communauté des développeurs. Il s’agit d’un framework tout-en-un qui fonctionne un peu comme un générateur de site statique.

Dans cet article, nous expliquerons pourquoi tant de développeurs apprécient Astro et le préfèrent à d’autres solutions. Nous vous expliquerons également comment construire un blog basé sur le markdown en utilisant le framework.

Qu’est-ce qu’Astro ?

Astro
Astro

Astro, ou Astro.js, est un générateur de site statique populaire conçu pour ceux qui souhaitent créer des sites web riches en contenu qui s’exécutent rapidement et en douceur. Sa légèreté, sa structure intuitive et sa courbe d’apprentissage douce le rendent attrayant pour les développeurs de tous niveaux d’expérience.

Malgré sa petite taille, Astro est livré avec des outils puissants qui augmentent considérablement la flexibilité de votre site, vous permettant ainsi de gagner des heures dans la gestion du contenu et des thèmes. De plus, les développeurs ont la possibilité de travailler avec leurs frameworks préférés en conjonction avec Astro – une perspective attrayante pour les codeurs chevronnés qui ont déjà une foule de favoris.

Voici quelques exemples de la façon dont Astro se démarque de la concurrence :

  • Architecture en îlots : Astro extrait votre interface utilisateur (UI) en composants plus petits et isolés, appelés « Astro Islands », qui peuvent être utilisés sur n’importe quelle page. Le JavaScript non utilisé est remplacé par du HTML léger.
  • Zéro JavaScript (par défaut) : Bien que vous puissiez utiliser tout le JavaScript que vous souhaitez pour créer vos sites web, Astro tentera de déployer zéro JavaScript en production en transcrivant votre code pour vous. C’est une approche parfaite si vous vous concentrez sur la vitesse du site.
  • SSG et SSR inclus : Astro a commencé comme un générateur de site statique (Static Site Generator ou SSG), mais en cours de route, il est devenu un framework qui utilise à la fois la génération de site statique et le rendu côté serveur (Server-Side Rendering ou SSR). Vous pouvez choisir les pages qui utiliseront l’une ou l’autre de ces approches.
  • Framework agnostique : Lorsque vous utilisez Astro, vous pouvez utiliser le framework JavaScript de votre choix, voire plusieurs frameworks à la fois. (Nous y reviendrons plus en détail dans la suite de cet article)

De plus, Astro est prêt à l’emploi, ce qui signifie qu’il peut être déployé n’importe où, n’importe quand, en toute simplicité.

Vous êtes prêt à en savoir plus ? Dans ce cas, nous allons nous pencher sur le fonctionnement d’Astro.

La structure d’Astro

Avant d’aller plus loin, il est important de comprendre comment Astro est structuré pour que vous puissiez l’utiliser efficacement. Jetons un coup d’œil à la structure de base des fichiers d’Astro :

├── dist/
├── src/
│   ├── components/
│   ├── layouts/
│   └── pages/
│       └── index.astro
├── public/
└── package.json

Comme vous pouvez le constater, la structure elle-même est assez simple. Cependant, il y a quelques points clés que vous devez garder à l’esprit :

  • La majeure partie de notre projet se trouve dans le dossier src. Vous pouvez classer vos composants, vos mises en page et vos pages dans des sous-dossiers. Vous pouvez ajouter des dossiers supplémentaires pour faciliter la navigation dans votre projet.
  • Le dossier public contient tous les fichiers qui vivent en dehors du processus de construction, tels que les polices, les images ou un fichier robots.txt.
  • Le dossier dist contient tout le contenu que vous souhaitez déployer sur votre serveur de production.

Ensuite, nous allons nous plonger dans les principaux composants d’Astro : les composants, les mises en page et les pages.

Les composants

Les composants sont des morceaux de code réutilisables qui peuvent être inclus dans l’ensemble de votre site web, à l’instar des codes courts de WordPress. Par défaut, ils ont l’extension de fichier .astro, mais vous pouvez également utiliser des composants non-Astro construits avec Vue, React, Preact ou Svelte.

Voici un exemple de ce à quoi ressemble un composant simple – dans ce cas, une balise div classée contenant une balise h2:

<!-- src/components/Kinsta.astro -->
<div class="kinsta_component">
    <h2>Hello, Kinsta!</h2>
</div>

Et voici comment nous pouvons incorporer ce composant dans notre site :

---
import KinstaComponent from ../components/Kinsta.astro
---
<div>
    <KinstaComponent />
</div>

Comme indiqué ci-dessus, vous devez d’abord importer le composant. Ce n’est qu’ensuite qu’il peut être inclus dans la page.

Il est maintenant temps d’ajouter quelques propriétés à notre composant. Commençons par la propriété {title}:

---
const { title = 'Hello' } = Astro.props
---

<div class="kinsta_component">
    <h2>{title}</h2>
</div>

Voici comment notre propriété sera mise en œuvre :

---
import KinstaComponent from ../components/Kinsta.astro
---

<div>
    
    <KinstaComponent title="Good day"/>

    
    <KinstaComponent />
 </div>

C’est simple, non ?

Comme vous l’avez probablement déjà compris, la véritable puissance des composants Astro réside dans leur nature globale et réutilisable. Ils vous permettent d’apporter des changements radicaux à l’ensemble de votre site en ne modifiant que quelques lignes de code, ce qui peut vous faire gagner un nombre incalculable d’heures que vous auriez autrement consacrées à des remplacements de texte fastidieux et laborieux.

Mises en page

Parlons maintenant des mises en page. Outre leur fonction thématique familière, les mises en page dans Astro sont également des composants réutilisables, mais elles sont utilisées comme des enveloppes de code.

Jetez un coup d’œil à cet exemple :

---
// src/layouts/Base.astro
const { pageTitle = 'Hello world' } = Astro.props
---

<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width">
    <title>{pageTitle}</title>
</head>
<body>
    <main>
        <slot />
    </main>
</body>
</html>

Notez la balise <slot />. L’élément <slot /> d’Astro sert de placeholder pour les balises et le contenu HTML réels.

Voyons ce qu’il en est.

Le code ci-dessous montre que notre balise <slot /> est remplacée par le code que vous souhaitez, le tout étant enveloppé par notre mise en page Base.astro:

---
import Base from '../layouts/Base.astro';
---

<Base title="Hello world">
    <div>
        <p>Some example text.</p>
    </div>
</Base>

Comme vous pouvez le voir, notre balise <slot /> a été remplacée par le code HTML qu’elle représente, à savoir :

<div>
    <p>Some example text.</p>
</div>

Comme vous pouvez le constater, les mises en page, tout comme les composants, vous permettent de réutiliser des morceaux de code sur l’ensemble de votre site, ce qui simplifie la mise à jour de votre contenu global et de votre conception.

Pages

Les pages sont un type spécial de composant responsable du routage, du chargement des données et de la création de modèles.

Astro utilise le routage par fichier pour générer les pages, plutôt que le routage dynamique. Non seulement la méthode basée sur les fichiers consomme moins de bande passante, mais elle vous évite également d’avoir à importer vos composants manuellement.

Voici un exemple de routes définies :

src/pages/index.astro => yourdomain.com
src/pages/test.astro => domain.com/test
src/pages/test/subpage => domain.com/test/subpage

Avec ces routes, notre page d’accueil serait rendue comme suit :

<!-- src/pages/index.astro -->
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width">
    <title>Hello World</title>
</head>
<body>
    <h1>Hello, Kinsta</h1>
</body>
</html>

Mais nous savons déjà comment utiliser les mises en page, alors convertissons ceci en quelque chose de globalement accessible :

---
import Base from '../layouts/Base.astro';
---

<Base>
    <h1>Hello, Kinsta</h1>
</Base>

Voilà, c’est beaucoup plus propre.

Nous aborderons le routage dans Astro plus en détail dans la suite de cet article, mais pour l’instant, passons aux choses sérieuses : la construction et la personnalisation de sites.

Personnalisation et extension d’Astro

Il est temps d’apprendre à personnaliser votre site Astro ! Nous allons utiliser les collections Markdown, le routage, la gestion des images et une intégration avec React pour construire et personnaliser notre site statique.

Collections Markdown

Avec la version 2.0, Astro a introduit une bien meilleure façon de maintenir le contenu Markdown qu’auparavant. Grâce aux collections, nous pouvons être sûrs que toutes les données de notre frontmatter sont incluses et qu’elles ont le bon type d’association.

Dernièrement, dans la version 2.5, Astro a ajouté la possibilité de gérer également les fichiers JSON et YAML en tant que collections.

Prêt à vous salir les mains ?

Tout d’abord, placez tous vos articles Markdown dans le dossier src/content/collection_name. Nous allons créer une collection de blogs pour ce projet, donc dans notre démonstration, le dossier sera src/content/blog.

Il est maintenant temps de définir tous les champs frontmatter nécessaires dans notre fichier src/content/config.ts. Notre blog aura besoin des éléments suivants :

  • title (chaîne)
  • tags (tableau)
  • publishDate (heure)
  • image (chaîne, optionnel)

Voici à quoi ressemble l’ensemble :

import { z, defineCollection } from 'astro:content';

const blogCollection = defineCollection({ 
    schema: z.object({
        title: z.string(),
        tags: z.array(z.string()),
        image: z.string().optional(),
        publishDate: z.date(),
    }),
});

export const collections = {
    'blog': blogCollection,
};

Et voici ce que contient notre fichier Markdown article-about-astro.md:

---
title: Article about Astro
tags: [tag1, tag3]
publishDate: 2023-03-01
---
## Tamen risit

Lorem *markdownum flumina*, laceraret quodcumque Pachyne, **alter** enim
cadavera choro.

Il est vrai que notre fichier Markdown n’a rien de spécial. Mais il y a ici une magie cachée qui se manifestera si nous faisons une faute de frappe.

Disons, par exemple, qu’au lieu de saisir publishDate, nous avons accidentellement saisi publishData. Dans le cas d’une telle faute de frappe, Astro génère une erreur :

blog → article-about-astro.md frontmatter does not match collection schema.
  "publishDate" is required.

Incroyable, non ? Cette fonction astucieuse peut nous aider à trouver des erreurs relatives à la matière première en quelques secondes.

La dernière chose que nous devons ajouter est une page montrant nos données. Créons un fichier à src/page/blog/[slug].astro avec le code suivant :

---
import Base from '../../layouts/Base.astro';
import { getCollection } from 'astro:content';
export async function getStaticPaths() {
    const blogEntries = await getCollection('blog');
    return blogEntries.map(entry => ({
        params: { slug: entry.slug }, props: { entry },
  }));
}
const { entry } = Astro.props;
const { Content } = await entry.render();
---
<Base>
    <h1>{entry.data.title} </h1>
    <Content />
</Base>

Grâce à getStaticPaths, Astro créera toutes les pages statiques pour chaque article de la collection de blogs.

Il ne nous manque plus qu’une liste de tous nos articles :

---
import Base from '../../layouts/Base.astro';

import { getCollection } from 'astro:content';
const blogEntries = await getCollection('blog');
---
<Base>
<ul>
    {blogEntries.map(item => <li> <strong><a href={'/blog/' + item.slug}>{item.data.title}</a></strong></li>)}
</ul>
</Base>

Comme vous pouvez le constater, l’utilisation de collections rend cette tâche remarquablement simple.

Créons maintenant une collection de types de données. Tout d’abord, nous devons rouvrir le fichier src/content/config.ts et ajouter une nouvelle collection de données :

import { z, defineCollection, referenece } from 'astro:content';

const blogCollection = defineCollection({ 
	type: 'content',
    schema: z.object({
        title: z.string(),
        tags: z.array(z.string()),
        image: z.string().optional(),
        publishDate: z.date(),
	    author: reference('authors')
    }),
});

const authorsCollection = defineCollection({ 
	type: 'data',
    schema: z.object({
        fullName: z.string(),
        country: z.string()
    }),
});


export const collections = {
    'blog': blogCollection,
'authors': authorsCollection,
};

Outre la création d’une nouvelle collection, nous avons également ajouté la référence à l’auteur dans la collection blogCollection.

Il est temps de créer un nouvel auteur. Nous devons créer un fichier appelé maciek-palmowski.json dans le fichier content/authors.json :

{
    "fullName": "Maciek Palmowski",
    "country": "Poland"
}

La dernière chose qu’il nous reste à faire est de récupérer ces données dans notre publication. Pour cela, nous devons utiliser getEntry:

---
import Base from '../../layouts/Base.astro';
import { getCollection, getEntry } from 'astro:content';
export async function getStaticPaths() {
  const blogEntries = await getCollection('blog');
  return blogEntries.map(entry => ({
    params: { slug: entry.slug }, props: { entry },
  }));
}
const { entry } = Astro.props;
const author = await getEntry(entry.data.author);
const { Content } = await entry.render();
---
<Base>
<h1>{entry.data.title}</h1>
<h2>Author: {author.data.fullName}</h2>
<Content />
</Base>

Routage

Astro dispose de deux modes de routage différents. Nous avons déjà appris à connaître le premier – le routage statique (basé sur les fichiers) – lorsque nous avons abordé les pages plus tôt.

Nous allons maintenant nous intéresser au routage dynamique.

À l’aide des paramètres de routage dynamique, vous pouvez demander à un fichier de page Astro d’automatiser la création de plusieurs pages ayant la même structure. C’est utile lorsque vous avez beaucoup de pages d’un type particulier (biographies d’auteurs, profils d’utilisateurs, articles de documentation, etc.)

Dans l’exemple suivant, nous allons générer des pages de biographies pour nos auteurs.

Dans le mode de sortie statique par défaut d’Astro, ces pages sont générées au moment de la construction, ce qui signifie que vous devez prédéterminer la liste des auteurs qui recevront un fichier correspondant. En mode dynamique, en revanche, les pages sont générées sur demande pour tout itinéraire correspondant.

Si vous voulez passer une variable comme nom de fichier, ajoutez des crochets autour d’elle :

pages/blog/[slug].astro -> blog/test, blog/about-me 

Approfondissons la question en utilisant le code de notre fichier src/page/blog/[slug]:

---
import Base from '../../layouts/Base.astro';
import { getCollection } from 'astro:content';
export async function getStaticPaths() {
    const blogEntries = await getCollection('blog');
    return blogEntries.map(entry => ({
        params: { slug: entry.slug }, props: { entry },
  }));
}
const { entry } = Astro.props;
const { Content } = await entry.render();
---
<Base>
    <h1>{entry.data.title}</h1>
    <Content />
</Base>

La route getStaticPaths est responsable de la génération de toutes les pages statiques. Elle renvoie deux objets :

  • params: Utilisé pour remplir les parenthèses dans nos URL
  • props: Toutes les valeurs que nous transmettons à la page

Et avec cela, la génération de votre page est prise en charge.

Traitement des images

On ne peut parler de sites web performants sans évoquer les formats d’image modernes, les méthodes de redimensionnement correctes et le chargement différé.

Heureusement, Astro nous couvre ici aussi. Grâce au paquetage @astrojs/image, nous pouvons introduire tous ces éléments en quelques minutes.

Après avoir installé le paquet, nous avons accès à deux composants : Image et Picture.

Le composant Image est utilisé pour créer une balise <img /> optimisée. Voici un exemple :

---
import { Image } from '@astrojs/image/components';
import heroImage from '../assets/hero.png';
---

<Image src={heroImage} format="avif" alt="descriptive text" />
<Image src={heroImage} width={300} alt="descriptive text" />
<Image src={heroImage} width={300} height={600} alt="descriptive text" />

De même, le composant Picture permet de créer un composant <picture/> optimisé :

---
import { Picture } from '@astrojs/image/components';
import hero from '../assets/hero.png';
---
<Picture src={hero} widths={[200, 400, 800]} sizes="(max-width: 800px) 100vw, 800px" alt="descriptive text" />

SSG vs SSR

Par défaut, Astro fonctionne comme un générateur de site statique. Cela signifie que tout le contenu est converti en pages HTML statiques.

Bien qu’il s’agisse d’une approche parfaite à bien des égards (notamment en termes de rapidité), nous pouvons parfois préférer une approche plus dynamique. Si vous voulez une page de profil séparée pour chaque utilisateur, par exemple, ou si vous avez des milliers d’articles sur votre site, tout re-rendre à chaque fois prendrait beaucoup trop de temps.

Heureusement, Astro peut également fonctionner comme un framework entièrement rendu côté serveur ou dans un mode hybride entre les deux.

Pour activer le SSR côté serveur, nous devons ajouter le code suivant à astro.config.mjs:

import { defineConfig } from 'astro/config';

export default defineConfig({
    output: 'server'
});

C’est l’approche standard.

L’approche hybride signifie que, par défaut, tout est généré dynamiquement, à l’exception des pages auxquelles export const prerender = true a été ajouté.

Avec Astro 2.5, il est également possible de définir le rendu statique par défaut et de sélectionner manuellement les routes dynamiques.

Grâce à cela, nous pouvons, par exemple, créer un site web entièrement généré de manière statique avec des pages de connexion et de profil dynamiques. Sympathique, non ?

Vous pouvez en savoir plus à ce sujet dans la documentation officielle.

Intégration d’autres frameworks JavaScript

Une autre fonctionnalité étonnante d’Astro vous permet d’apporter votre framework préféré et de l’utiliser de concert avec Astro. Vous pouvez mélanger Astro avec React, Preact, Svelte, Vue, Solid, ou Alpine (pour toutes les intégrations, voir la documentation « Add Integrations » d’Astro).

Disons que nous voulons utiliser React. Tout d’abord, nous devons installer l’intégration en exécutant ce qui suit dans npm:

npx astro add react

Maintenant que React a été intégré, nous pouvons créer un composant React. Dans notre cas, il s’agira du composant counter dans src/components/ReactCounter.tsx:

import { useState } from 'react';

/** A counter written with React */
export function Counter({ children }) {
    const [count, setCount] = useState(0);
    const add = () => setCount((i) => i + 1);
    const subtract = () => setCount((i) => i - 1);

    return (
        <>
            <div className="counter">
                <button onClick={subtract}>-</button>
                <pre>{count}</pre>
                <button onClick={add}>+</button>
                </div>
            <div className="counter-message">{children}</div>
        </>
    );
}

Enfin, nous devons placer le compteur sur notre page avec le code suivant :

---
import * as react from '../components/ReactCounter';
---
<main>
    <react.Counter client:visible />
</main>

Et voilà : votre composant React a été intégré de manière transparente dans votre site.

Comment déployer Astro avec Kinsta

Il est maintenant temps d’obtenir notre site Astro sur le web. Heureusement, Kinsta est l’hébergeur parfait pour un hébergement de site statique rapide et sans douleur.

Commencez par créer un dépôt GitHub pour les fichiers de votre site. Si vous n’êtes pas prêt à utiliser vos propres fichiers, vous pouvez cloner le modèle de site Astro que notre équipe a créé.

Une fois que votre dépôt est prêt, suivez les étapes ci-dessous pour déployer votre site statique sur Kinsta :

    1. Connectez-vous ou créez un compte pour voir votre tableau de bord MyKinsta.
    2. Autorisez Kinsta avec votre fournisseur Git.
    3. Cliquez sur Sites statiques dans la colonne latérale de gauche, puis sur Ajouter un site.
    4. Sélectionnez le dépôt et la branche à partir desquels vous souhaitez effectuer le déploiement.
    5. Attribuez un nom unique à votre site.
    6. Ajoutez les réglages de construction dans le format suivant :
      • Commande de construction : npm run build
      • Version de Node : 18.16.0
      • Répertoire de publication : dist
    7. Enfin, cliquez sur Créer un site.

Et c’est tout ! Vous avez maintenant un site statique en production, entièrement fonctionnel, créé avec le framework Astro.

Notre page d'accueil Astro
Notre page d’accueil Astro

Vous trouverez votre URL de production et d’autres détails de déploiement dans l’onglet Déploiements.

Comme alternative à l’hébergement de site statique, vous pouvez opter pour le déploiement de votre site statique avec l’hébergement d’applications de Kinsta, qui fournit une plus grande flexibilité d’hébergement, un plus large éventail d’avantages et l’accès à des fonctionnalités plus robustes. Par exemple, l’évolutivité, le déploiement personnalisé à l’aide d’un fichier Docker, et des statistiques complètes englobant des données en temps réel et historiques.

Résumé

La structure claire d’Astro, sa syntaxe simple et ses composants globaux rendent la construction et l’exécution d’une application vraiment facile. sa légèreté et sa double utilisation du routage statique et dynamique augmentent considérablement la réactivité du site, tandis que sa capacité à coopérer avec d’autres frameworks JavaScript le rend d’autant plus attrayant pour les codeurs expérimentés.

Si votre objectif est de créer un site riche en contenu qui se charge rapidement, qui offre des fonctionnalités modulaires et qui permet une génération à la fois statique et dynamique, Astro pourrait être le bon choix pour vous.

Vous pouvez héberger gratuitement votre site web statique avec l’hébergement de sites statiques de Kinsta.

Que pensez-vous du générateur de sites statiques Astro ? L’avez-vous utilisé dans le cadre d’un projet personnel ? Faites-nous en part dans la section des commentaires ci-dessous.

Maciek Palmowski

Maciek is a web developer working at Kinsta as a Development Advocate Analyst. After hours, he spends most of his time coding, trying to find interesting news for his newsletters, or drinking coffee.