Skip to content

Spécification : Middleware Astro Preview

Spécification : Middleware Astro Preview

Documentation technique

Slice : Slice 1 (Page d’accueil)
Cycle : DOC → SPEC → CODE → TEST → INTÉG
Statut : SPEC

1. Objectif

Implémenter un middleware Astro pour détecter le mode preview et injecter une bannière d’information dans toutes les pages (prerendered et SSR), permettant aux collaborateurs de savoir qu’ils sont en mode preview et de quitter ce mode facilement.

2. Configuration technique

2.1. Middleware Astro

Fichier : apps/web/src/middleware.ts

Configuration :

  • TypeScript
  • Exécution côté serveur
  • Accès aux cookies de la requête
  • Modification de la réponse HTML

2.2. Pattern d’injection1/2

Injection de bannière :

  • Détecter la balise <body> dans le HTML
  • Insérer la bannière après <body>
  • Ne pas modifier le reste du HTML

2.2. Pattern d’injection2/2

HTML de la bannière :

<div class="preview-banner">
⚠️ <strong>Mode Preview Activé</strong> — Visualisation des brouillons Sanity non publiés (Drafts).
<a href="/api/exit-preview" class="exit-link">Quitter la preview</a>
</div>

3. Structure des fichiers

3.1. Middleware

Fichier : apps/web/src/middleware.ts

Structure :

import { defineMiddleware } from 'astro:middleware';
export const onRequest = defineMiddleware((context, next) => {
// Détection cookie et injection bannière
});

3.2. Styles

Options :

  • Styles inline dans la bannière
  • Ou fichier CSS séparé importé

4. Implémentation du middleware

Logique :

const isPreview = context.cookies.get('sanity-preview')?.value === 'true';

4.2. Gestion de route exit-preview

Logique :

if (context.url.pathname === '/api/exit-preview') {
const response = new Response(null, {
status: 307,
headers: {
'Location': '/',
'Set-Cookie': 'sanity-preview=; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=0'
}
});
return response;
}

4.3. Injection de bannière

Logique :

if (isPreview) {
const response = await next();
const html = await response.text();
const modifiedHtml = html.replace(
'<body>',
'<body>' + previewBannerHtml
);
return new Response(modifiedHtml, {
headers: response.headers
});
}

5. Comportement attendu

5.1. Pages prerendered (SSG)

Comportement :

  • Le middleware détecte le cookie (contrairement aux composants)
  • La bannière est injectée dans le HTML statique
  • Respecte l’ADR-SSR-Pur.md (index.astro reste prerendered)

5.2. Pages SSR

Comportement :

  • Le middleware détecte le cookie
  • La bannière est injectée dans le HTML généré
  • Cohérence avec les pages prerendered

5.3. Route exit-preview

Comportement :

  • Middleware intercepte /api/exit-preview
  • Supprime le cookie sanity-preview
  • Redirect vers /
  • Code HTTP 307

6. Tests et validation

6.1. Tests de middleware

Scénarios :

  1. Sans cookie preview : Page s’affiche normalement sans bannière
  2. Avec cookie preview : Bannière injectée après <body>
  3. Route exit-preview : Cookie supprimé et redirect vers /
  4. Page prerendered : Bannière injectée dans HTML statique
  5. Page SSR : Bannière injectée dans HTML généré

6.2. Commandes de test

Commandes :

Terminal window
task build:web
task dev

Tests manuels :

  • Tester index.astro avec cookie preview
  • Tester [slug].astro avec cookie preview
  • Tester la route /api/exit-preview

7. Intégration avec l’existant

7.1. Compatibilité avec index.astro

État actuel :

  • index.astro est prerendered (export const prerender = true)
  • Ne peut pas détecter les cookies dans le composant
  • Le middleware détectera le cookie et injectera la bannière

Modification requise :

  • Retirer la logique de bannière preview de index.astro (déjà fait)
  • Garder le mode prerendered

7.2. Compatibilité avec [slug].astro

État actuel :

  • [slug].astro est SSR (export const prerender = false)
  • Détecte déjà le cookie dans le composant
  • Affiche déjà la bannière preview

Modification requise :

  • Garder la logique existante (cohérence)
  • Le middleware injectera aussi la bannière (non problématique)

7.3. Compatibilité avec welcome.astro

État actuel :

  • welcome.astro est SSR
  • Détecte le cookie et affiche la bannière

Modification requise :

  • Aucune modification nécessaire
  • Le middleware injectera aussi la bannière (cohérence)

8. Problèmes potentiels et solutions

8.1. Performance

Problème : Modification du HTML à chaque requête avec cookie preview

Solution :

  • Le middleware ne modifie que si cookie présent
  • Impact minimal (detection cookie + replace simple)
  • Cache désactivé pour les requêtes avec cookie preview

8.2. Injection HTML

Problème : Le pattern <body> peut ne pas exister ou être différent

Solution :

  • Vérifier que <body> existe avant injection
  • Fallback : pas de bannière si structure HTML invalide

8.3. Double bannière

Problème : SSR pages affichent déjà la bannière

Solution :

  • Option 1 : Retirer la logique SSR (cohérence)
  • Option 2 : Garder les deux (non problématique visuellement)
  • Recommandation : Retirer la logique SSR pour cohérence

9. Checklist de validation

Avant de passer à l’étape CODE :

  • Spécification technique complète
  • Pattern d’injection défini
  • Route exit-preview spécifiée
  • Tests définis
  • Intégration avec l’existant analysée
  • Problèmes potentiels identifiés

10. Approbation

Validation requise : Confirmer que la spécification peut passer à l’étape CODE.

11. Historique des modifications

Date Version Description Auteur
2026-09-17 1.0 Création initiale Devin
Switch to normal mode

Contents