Composed

Astro passe en version 6 - Analyse des nouveautés et test d'upgrade

Astro passe en version 6 : tour d'horizon et analyse des nouveautés majeures et test de migration.

Publié le par Emmanuel LASTRA Mis à jour le 8 min de lecture

Astro passe en version 6 - Analyse des nouveautés et test d'upgrade
Astro

Le meta-framework Astro franchit une nouvelle étape avec Astro 6, une version majeure qui met l’accent sur l’expérience développeur et la cohérence entre développement local et production. Cette mise à jour introduit un runtime de développement repensé, de nouvelles capacités autour du contenu dynamique et plusieurs améliorations pour la gestion des dépendances. L’objectif est clair : simplifier le développement d’applications web tout en conservant les performances et la simplicité qui font la réputation d’Astro.

Après un point sur les nouveautés d’Astro 6, je vais tester la migration de ce site vers la nouvelle version pour utiliser certaines des nouveautés introduites. Si vous voulez passer directement à la pratique, n’hésitez pas à sauter à la section suivante.

Les nouveautés d’Astro 6

Un serveur de dev aligné sur la production

Le serveur astro dev a été revu pour s’appuyer sur la nouvelle Environment API de Vite 7. Le dev server et le pipeline de build partagent désormais les mêmes chemins de code, ce qui élimine la principale source de divergences entre développement local et production.

L’impact est particulièrement concret pour les projets ciblant des runtimes non-Node : Cloudflare Workers, Bun, Deno. Jusqu’ici, ces runtimes ne pouvaient pas être simulés localement, donc les bugs ne se manifestaient qu’après déploiement. L’adaptateur @astrojs/cloudflare bénéficie directement de ce changement : il exécute désormais workerd (le runtime Cloudflare open source) à chaque étape (développement, prérendu et production). Les bindings KV, D1, R2 et Durable Objects sont accessibles localement, sans couche de simulation, plus besoin de Astro.locals.runtime.

API Font native

Astro 6 intègre une API dédiée à la gestion des polices web. On déclare ses fonts dans astro.config.mjs (fichiers locaux ou providers), et Astro prend en charge le téléchargement, la mise en cache pour auto-hébergement, les fallbacks optimisés et l’injection des <link rel="preload">. J’ai testé cette API dans la section pratique.

Live Content Collections stables

Les Live Content Collections passent en stable. Là où les content collections classiques nécessitent un rebuild complet pour refléter un changement, les live collections récupèrent le contenu à la requête, sans toucher au pipeline de build. Elles utilisent les mêmes APIs (getCollection(), getEntry(), schemas, loaders), et les deux modes peuvent coexister dans le même projet.

Content Security Policy native

Astro 6 est le premier meta-framework JavaScript à proposer une gestion native des CSP pour les pages statiques et dynamiques. Astro calcule les hashes de tous les scripts et styles qu’il génère et les injecte automatiquement dans les headers. Un simple flag suffit pour la plupart des sites, avec une API complète disponible pour les cas avancés. J’ai évalué cette fonctionnalité dans la section pratique sans l’implémenter pour le moment car le site utilise déjà une CSP gérée au niveau nginx, et la compatibilité avec Shiki (le highlighter de code utilisé) n’est pas encore au rendez-vous.

Fonctionnalités expérimentales notables

  • Compilateur Rust : successeur du compilateur Go actuel, déjà plus rapide et plus fiable sur certains cas. Activable via experimental.rustCompiler.
  • Queued Rendering : remplace le rendu récursif par une approche en deux passes. Benchmarks à +2x sur les performances de rendu. Prévu comme défaut dans Astro 7.
  • Route Caching : API de cache agnostique de la plateforme pour les pages SSR, avec stale-while-revalidate et invalidation par tags.

Mises à jour des dépendances

DépendanceAvantAprès
Node.js18 / 2022+ (obligatoire, attention au déploiement)
Vite57
Shiki24
Zod34 (import z depuis astro/zod)

En pratique

Score pageSpeed Insights avant la migration

Mobile : PageSpeed Insights mobile avant migration

Desktop : PageSpeed Insights desktop avant migration

Une légère latence identifiée sur les polices, mais globalement de très bonnes performances. PageSpeed latence polices

Tentons l’upgrade

Ce site étant construit avec Astro, je vais profiter de cette mise à jour pour migrer vers la version 6 et tester les nouveautés ou au moins en évaluer la pertinence sur le projet en cours.

Même si la version est stable et qu’une bonne compatibilité est assurée, il est recommandé de tester la migration sur une branche dédiée avant de l’intégrer à la branche principale.

Pour mettre à jour un projet Astro existant, il suffit d’utiliser l’une des deux commandes suivantes :

npx @astrojs/upgrade

ou

npm install astro@latest

Pour ma part j’ai opté pour la première option, qui permet de bénéficier d’une expérience de migration guidée, d’avoir des alertes sur les packages impactés et de vérifier les étapes à suivre pour assurer une transition en douceur vers Astro 6. La migration va ici s’effectuer de V5.17.1 vers V6.0.2.

Pas d’erreur au build la migration semble s’être déroulée sans accroc. Je vais maintenant tester ou évaluer les nouveautés.

Migration vers l’API Font native

Le site utilisait jusqu’ici une approche manuelle pour charger les polices Inter et Rajdhani depuis le package @fontsource. Voici ce que la migration vers l’API Font d’Astro 6 a changé concrètement.

Avant

  • Installation manuelle des packages @fontsource/inter et @fontsource/rajdhani
  • Divers @import dans global.css pour couvrir les variantes de poids et de subset
  • Un plugin PostCSS custom pour forcer font-display: optional sur tous les @font-face générés
  • Une intégration Astro maison (injectFontPreloads) qui parcourait les fichiers HTML après le build pour injecter les balises <link rel="preload"> nécessaire car les hash des fichiers woff2 changent à chaque build

PageSpeed Insights affichait un score satisfaisant pour les performances liées aux polices en notant toutefois une légère latence associé, mais le code était assez verbeux et nécessitait plusieurs étapes manuelles.

Après

// astro.config.mjs
fonts: [
  {
    provider: fontProviders.fontsource(),
    name: 'Inter',
    cssVariable: '--font-inter',
    weights: [400, 600, 700],
    styles: ['normal'],
    subsets: ['latin', 'latin-ext'],
    display: 'optional',
  },
  // idem pour Rajdhani
]
<!-- MainHead.astro -->
<Font cssVariable="--font-inter" preload />
<Font cssVariable="--font-rajdhani" preload />

Astro gère maintenant lui-même le téléchargement des fichiers woff2, leur mise en cache dans .astro/fonts/, l’injection des <link rel="preload"> et la valeur de font-display. Le code du projet est sensiblement allégé : environ 80 lignes supprimées entre le plugin PostCSS, l’intégration post-build et les imports CSS, remplacées par quelques lignes de configuration déclarative.

CSP native : une bonne idée, mais pas sans prérequis

Astro 6 introduit une gestion native des Content Security Policy via security.csp dans astro.config.mjs. L’objectif est séduisant : plutôt que de rédiger manuellement des directives CSP dans les headers nginx ou un fichier _headers, Astro génère des hashes automatiquement pour chaque bloc <style> et <script> qu’il produit, et les injecte dans une balise <meta http-equiv="content-security-policy">.

// astro.config.mjs
security: {
  csp: {
    directives: [
      "default-src 'self'",
      "img-src 'self' data: https:",
    ],
    scriptDirective: {
      resources: ["'self'", "https://www.googletagmanager.com"],
    },
  }
}

Le blocage : Shiki et les styles inline

La CSP Astro repose sur des hashes de styles ce qui est incompatible avec Shiki, le highlighter de code utilisé par défaut. Shiki applique la coloration syntaxique via des attributs style inline sur chaque token :

<span style="color:#79c0ff">const</span>

Les inline styles ne peuvent être autorisés en CSP qu’avec la directive 'unsafe-inline'. Or, dès qu’un hash est présent dans style-src, les navigateurs ignorent automatiquement 'unsafe-inline', c’est le comportement voulu. Résultat : les blocs de code perdraient toute coloration.

Astro documente explicitement cette limitation : “Shiki isn’t currently supported [with CSP]. Consider using <Prism /> when your project requires both CSP and syntax highlighting.”

Prism contourne le problème en générant des classes CSS (<span class="token keyword">) plutôt que des styles inline. Mais migrer de Shiki vers Prism uniquement pour débloquer la CSP native représente un compromis non négligeable.

Ce qui a été retenu

Pour ce site, la CSP est déjà gérée au niveau nginx (nginx-security-headers.conf). Cette approche reste plus flexible : elle couvre l’ensemble des réponses HTTP sans dépendre du framework, et permet d’intégrer 'unsafe-inline' de façon ciblée tant que Shiki est en place.

La CSP native d’Astro reste une bonne option pour les projets qui démarrent avec Prism, ou qui n’utilisent pas de blocs de code. Pour les autres, le compromis Shiki → Prism mérite d’être évalué au regard de l’apport réel.

Mises à jour des dépendances : points d’attention

Astro 6 embarque des mises à jour majeures de plusieurs dépendances clés qui peuvent avoir des incidences concrètes sur un projet existant.

Node.js 22 obligatoire

Astro 6 abandonne Node 18 et Node 20, qui ont atteint ou approchent leur fin de vie. Node 22 est désormais requis. Sur ce projet, la version locale était déjà en 22.x mais le Dockerfile de build utilisait encore node:20-alpine et aurait produit une erreur au prochain build de production. C’est corrigé.

Zod 4 et l’import de z

Astro 6 passe de Zod 3 à Zod 4 pour la validation des schemas de content collections. Le changement notable : z ne doit plus être importé depuis astro:content mais depuis astro/zod :

// Avant (Astro 5)
import { z, defineCollection } from 'astro:content';

// Après (Astro 6)
import { z } from 'astro/zod';
import { defineCollection } from 'astro:content';

Sur ce projet, content.config.ts a été mis à jour en conséquence. Zod 4 apporte par ailleurs des améliorations de performances et des messages d’erreur plus lisibles.

Vite 7 et Shiki 4

Astro 6 intègre Vite 7 et Shiki 4. La mise à jour de Vite 7 est transparente ici @tailwindcss/vite a suivi. Shiki 4 apporte des améliorations internes sans changement visible pour l’utilisateur final.

Impact sur les performances

Après mise en production suite upgrade les performances restent sensiblement identiques mais la marge de progression était limitée. PageSpeed ne met plus en avant de latence liée aux polices, ce qui suggère que l’API Font d’Astro 6 gère efficacement et sans effet de FOUT, le téléchargement et la mise en cache des fichiers de polices. La migration vers l’API Font a permis de simplifier considérablement le code du projet, tout en maintenant les performances liées aux polices à un niveau élevé.

En revanche les flux RSS sont revenus vides après la migration sans erreur au build, un point qui a nécessité une investigation plus approfondie. La cause était l’absence d’un loader dans la définition de la collection, ce qui fait que getCollection() retourne silencieusement un tableau vide. L’ajout du loader glob dans content.config.ts a suffi à rétablir les flux RSS. Ce problème a permis de mettre en évidence un besoin de refactorisation plus large du projet pour migrer toutes les pages vers getCollection().

Source Astro 6 release blog article