Skip to content

Exporter Astro en HTML statique

Le but n’est pas de produire une application Astro finale. Le but est d’utiliser Astro comme outil de fabrication pour composer des pages, les rendre en HTML/CSS statique, puis reprendre le résultat dans une intégration classique comme .NET WebForms.

Cette page ne redétaille pas toute l’architecture. Elle sert de procédure d’export. Les deux architectures de référence sont ici :

  1. Architecture Astro Bootstrap 4.6 + jQuery
  2. Architecture Astro Tailwind v4 + React

Astro permet deux variantes propres pour ce projet.

Choisir Bootstrap 4.6 + jQuery + composants .astro si :

  1. l’intégration finale doit rester très proche d’un HTML classique ;
  2. Bootstrap 4.6 est imposé ou déjà utilisé ;
  3. les interactions doivent rester en jQuery ou JavaScript global ;
  4. le back doit pouvoir reprendre le HTML sans runtime React ;
  5. les composants Astro servent surtout à découper le HTML en blocs lisibles.

Dans cette variante :

  1. Layout.astro charge Bootstrap, jQuery, Bootstrap bundle, custom.css et le script global ;
  2. src/components/*.astro contient les blocs HTML ;
  3. src/styles/custom.css contient les surcharges projet ;
  4. public/navbar.js est le script global de navbar ;
  5. src/assets/ contient les images importées par Astro ;
  6. public/ contient les fichiers servis tels quels.

Choisir Tailwind v4 + React + composants .tsx si :

  1. le projet veut composer les blocs en React ;
  2. Tailwind doit porter le style principal ;
  3. les composants ont des props, variantes ou conditions plus lisibles en TSX ;
  4. l’hydratation React doit rester possible mais explicite ;
  5. le build doit rester statique par défaut.

Dans cette variante :

  1. Layout.astro importe custom.css ;
  2. custom.css importe Tailwind avec @import "tailwindcss"; ;
  3. src/components/*.tsx contient les composants React ;
  4. les composants React restent statiques sans directive client:* ;
  5. public/navbar.js reste optionnel pour du JavaScript global non React ;
  6. src/assets/ et public/ gardent les mêmes rôles que dans la variante Bootstrap.

Les deux variantes partagent la même base de configuration.

astro.config.mjs
// @ts-check
import { defineConfig } from "astro/config";
export default defineConfig({
output: "static",
build: {
assetsPrefix: ".",
},
vite: {
build: {
cssCodeSplit: true,
assetsInlineLimit: 0,
},
},
});

Pour Tailwind + React, ajouter les intégrations nécessaires comme indiqué dans la page dédiée :

astro.config.mjs
import react from "@astrojs/react";
import tailwindcss from "@tailwindcss/vite";
export default defineConfig({
output: "static",
integrations: [react()],
build: {
assetsPrefix: ".",
},
vite: {
plugins: [tailwindcss()],
build: {
cssCodeSplit: true,
assetsInlineLimit: 0,
},
},
});

Les points importants :

  1. output: "static" force une sortie statique ;
  2. assetsPrefix: "." aide à obtenir des liens relatifs vers les assets Astro ;
  3. assetsInlineLimit: 0 évite d’embarquer des assets en base64 ;
  4. cssCodeSplit: true garde les fichiers CSS séparés quand Vite en produit.

Travailler page par page.

  1. Créer ou modifier une page dans src/pages/.
  2. Assembler les blocs depuis src/components/.
  3. Stabiliser le rendu visuel.
  4. Vérifier le HTML généré.
  5. Passer à la page suivante.

Pour une intégration WebForms propre, chaque page doit pouvoir devenir un gabarit HTML/CSS autonome.

Dans la variante Tailwind React, ne pas hydrater les composants React par réflexe.

Ne pas ajouter :

  1. client:load ;
  2. client:idle ;
  3. client:visible ;
  4. client:media ;
  5. client:only.

Pourquoi :

  1. un composant React sans directive client:* est rendu en HTML statique ;
  2. un composant avec directive client:* ajoute du JavaScript React au navigateur ;
  3. ce JavaScript complique la reprise dans une intégration classique si elle n’en a pas besoin.

Avant l’export, décider interaction par interaction.

Pour une sortie HTML classique :

  1. figer les menus, onglets, modales ou filtres si l’interaction n’est pas indispensable ;
  2. déplacer les comportements simples dans public/navbar.js ;
  3. garder des sélecteurs stables avec des id explicites ;
  4. valider que le JavaScript global ne dépend pas d’un état React.

Exemple de cible HTML classique :

<button id="navbar-toggle" type="button" aria-expanded="false">Menu</button>
<div id="navbarNav" class="collapse">...</div>
<script is:inline src="./navbar.js"></script>

Pour une sortie React hydratée :

  1. garder l’état dans le composant React ;
  2. ajouter explicitement client:load ou une autre directive client:* ;
  3. accepter que le navigateur charge du JavaScript React.

Lancer :

Terminal window
npm run build

Astro génère le site dans dist/.

Dans le projet test-bootstrap, le build validé sort notamment :

dist/
index.html
favicon.ico
favicon.svg
navbar.js
_astro/
client.[hash].js
index@_@astro.[hash].css

Le fichier client.[hash].js peut exister dans _astro/ même si la page ne l’utilise pas directement. Ce qui compte est le contenu de dist/index.html et les fichiers effectivement référencés par la page.

Après le build, vérifier les fichiers HTML générés.

Contrôles minimums :

  1. les liens CSS pointent vers ./_astro/... ou vers les CDN attendus ;
  2. les scripts globaux sont bien présents si la page en dépend ;
  3. les favicons viennent de public/ ;
  4. les images importées depuis src/assets/ ont été générées correctement ;
  5. aucun composant React ne charge de runtime navigateur sans décision explicite ;
  6. le rendu fonctionne hors racine web si c’est une contrainte d’intégration.

Si le back préfère un seul fichier CSS final, regrouper le CSS après validation du rendu, pas avant. Laisser Astro/Vite produire les fichiers d’abord évite un travail manuel inutile.

Le dossier à livrer est dist/.

Workflow recommandé :

  1. construire la page dans Astro ;
  2. choisir la variante d’architecture ;
  3. garder React statique sauf besoin explicite ;
  4. déplacer les interactions simples vers JavaScript classique si nécessaire ;
  5. lancer npm run build ;
  6. vérifier dist/index.html ;
  7. livrer dist/.

Les anciens scripts export-static.mjs et relativize-export.mjs ne sont pas nécessaires pour le projet testé.

Raisons :

  1. Astro sort déjà les fichiers dans dist/ ;
  2. dist/client n’existe pas dans cette configuration ;
  3. assetsPrefix: "." produit déjà des liens relatifs vers les assets Astro ;
  4. le build valide en une commande avec npm run build.

Ces scripts ne deviennent utiles que dans un cas particulier : un autre mode de build produit vraiment des URLs absolues impossibles à reprendre telles quelles, et la configuration Astro ne suffit pas à les corriger.