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
4.1. Détection du cookie
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 :
- Sans cookie preview : Page s’affiche normalement sans bannière
- Avec cookie preview : Bannière injectée après
<body> - Route exit-preview : Cookie supprimé et redirect vers
/ - Page prerendered : Bannière injectée dans HTML statique
- Page SSR : Bannière injectée dans HTML généré
6.2. Commandes de test
Commandes :
task build:webtask devTests 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 |