Skip to content

Test : Correction du Presentation Tool - Documents non affichés et Draft Mode

Le Presentation Tool de Sanity avait deux problèmes :

  1. Il n’affichait qu’un seul document (“Homepage Test Page”) dans le panneau “Documents on this page”
  2. Les documents draft ne pouvaient pas être prévisualisés (page blanche)

Le panneau “Documents on this page” ne montre que les documents dont le contenu est effectivement rendu sur la page courante avec l’encodage stega. La page d’accueil (/) ne charge que le document page avec slug.current == "/", donc seul ce document apparaissait.

Le Presentation Tool ne pouvait pas activer le draft mode car :

  • La configuration CORS n’était pas correcte
  • La configuration allowOrigins manquait dans le Presentation Tool
  • Le secret généré dynamiquement par le Presentation Tool n’était pas validé correctement

Problème 3 : Images manquantes dans les posts

Section titled “Problème 3 : Images manquantes dans les posts”

Les posts Sanity ne chargeaient pas les images (author image et main image) car les champs d’image n’étaient pas inclus dans la requête GROQ.

La route /blog/[...slug].astro (content collections Markdown) était en conflit avec la route /blog/[slug].astro (Sanity posts). Le catch-all interceptait toutes les requêtes.

Ajout de la configuration mainDocuments dans apps/studio/sanity/presentation/resolve.ts pour mapper les URLs aux documents principaux.

Solution 2 : Configuration CORS et allowOrigins

Section titled “Solution 2 : Configuration CORS et allowOrigins”
  • Ajout de allowOrigins: ['http://localhost:*'] dans sanity.config.ts
  • Ajout de l’origine http://localhost:4321 avec credentials dans le projet Sanity

Solution 3 : Support des images dans les posts

Section titled “Solution 3 : Support des images dans les posts”

Ajout des champs d’image dans la requête GROQ pour /blog/[slug].astro :

  • mainImage avec asset, alt, hotspot, crop
  • author.image avec asset, alt, hotspot, crop
  • Support des images dans le Portable Text renderer (_type == "image")

Suppression du catch-all /blog/[...slug].astro et fusion de la logique dans /blog/[slug].astro :

  • Tentative de chargement depuis Sanity en premier
  • Fallback vers les content collections Markdown si aucun post Sanity trouvé
  • Suppression du conflit de route

Fichier : apps/studio/sanity/presentation/resolve.ts

import { defineLocations, defineDocuments, PresentationPluginOptions } from 'sanity/presentation'
// ... (fonction slugToHref inchangée)
export const resolve: PresentationPluginOptions['resolve'] = {
locations: {
// ... (locations inchangées)
},
mainDocuments: defineDocuments([
{
route: '/welcome',
filter: `_type == "amn" && status == "active"`,
},
{
route: '/:slug',
filter: `_type == "page" && slug.current == $slug`,
},
{
route: '/blog/:slug',
filter: `_type == "post" && slug.current == $slug`,
},
]),
}

Fichier : apps/studio/sanity.config.ts

presentationTool({
resolve,
previewUrl: {
initial: SITE_URL,
previewMode: {
enable: '/api/draft-mode/enable',
},
},
allowOrigins: ['http://localhost:*'], // Ajouté pour cross-origin
}),

Configuration CORS :

Terminal window
npx sanity cors add http://localhost:4321 --credentials --project-id 4wa7mvsz

Fichier : apps/web/src/pages/blog/[slug].astro

// Query modifiée pour inclure les images
const { data: post } = await loadQuery({
query: `*[_type == "post" && slug.current == $slug][0]{
_id,
_type,
title,
slug,
publishedAt,
mainImage{
asset->{_id, url, metadata { lqip, dimensions } },
alt,
hotspot,
crop
},
body[]{
_type,
_key,
...select(
_type == "block" => { /* ... */ },
_type == "image" => {
asset->{_id, url, metadata { lqip, dimensions } },
alt
}
)
},
author->{
_id,
name,
slug,
image{
asset->{_id, url, metadata { lqip, dimensions } },
alt,
hotspot,
crop
}
},
categories[]->{
_id,
title
}
}`,
params: { slug },
cookies: Astro.cookies,
});
// Fallback vers content collections si aucun post Sanity
if (!post) {
const posts = await getCollection('blog');
contentPost = posts.find(p => p.id === slug);
// ...
}
  1. Les serveurs Astro et Studio doivent être en cours d’exécution
  2. Le mode edit doit être activé dans le Presentation Tool

Test 1 : Documents affichés dans le panneau

Section titled “Test 1 : Documents affichés dans le panneau”
  1. Ouvrir le Studio Sanity

    • Naviguer vers http://localhost:3333
    • S’authentifier si nécessaire
  2. Activer le Presentation Tool

    • Cliquer sur l’onglet “Presentation” dans le Studio
    • Activer le toggle “Edit” pour le mode visual editing
  3. Tester sur la page d’accueil (/)

    • Dans l’iframe, naviguer vers http://localhost:4321/
    • Vérifier que le panneau “Documents on this page” affiche le document page correspondant à la homepage
    • Le document doit apparaître avec son titre (ex: “Homepage Test Page”)
  4. Tester sur une page de type page

    • Dans l’iframe, naviguer vers une page existante de type page (ex: http://localhost:4321/test1)
    • Vérifier que le panneau “Documents on this page” affiche le document page correspondant
    • Le document doit apparaître avec son titre
  5. Tester sur la page welcome (/welcome)

    • Dans l’iframe, naviguer vers http://localhost:4321/welcome
    • Vérifier que le panneau “Documents on this page” affiche le document amn actif
    • Le document doit apparaître avec son message
  6. Tester sur une page de blog (si existante)

    • Dans l’iframe, naviguer vers une page de blog (ex: http://localhost:4321/blog/mon-article)
    • Vérifier que le panneau “Documents on this page” affiche le document post correspondant
    • Le document doit apparaître avec son titre

Test 2 : Prévisualisation des documents draft

Section titled “Test 2 : Prévisualisation des documents draft”
  1. Créer un document draft dans le Studio

    • Aller dans le Studio et créer un nouveau document de type page
    • Remplir les champs (title, slug, etc.)
    • Ne pas publier le document (garder en draft)
  2. Prévisualiser le document draft

    • Dans le Presentation Tool, naviguer vers l’URL du document draft (ex: http://localhost:4321/mon-slug-draft)
    • Vérifier que le contenu du document draft s’affiche correctement
    • Le mode edit doit être activé automatiquement
  3. Modifier le document draft

    • Modifier un champ du document draft dans le Studio
    • Vérifier que les changements apparaissent immédiatement dans la prévisualisation
    • Le composant SanityVisualEditing doit déclencher un rechargement automatique
  4. Tester avec d’autres types de documents

    • Créer un document draft de type amn
    • Prévisualiser sur /welcome
    • Vérifier que le message draft s’affiche
  1. Ouvrir un post Sanity existant

    • Dans le Studio, naviguer vers un document de type post (ex: “Welcome to OCI”)
    • Vérifier que le post a une mainImage configurée
    • Vérifier que l’author a une image configurée
  2. Prévisualiser le post publié

    • Dans le Presentation Tool, naviguer vers l’URL du post (ex: http://localhost:4321/blog/welcome-to-oci)
    • Vérifier que la mainImage s’affiche correctement
    • Vérifier que l’image de l’author s’affiche correctement
    • Vérifier que le titre, la date de publication, et les catégories s’affichent
  3. Prévisualiser un post draft

    • Créer un nouveau document de type post avec une mainImage et un author avec image
    • Ne pas publier le document
    • Dans le Presentation Tool, naviguer vers l’URL du post draft
    • Vérifier que toutes les images s’affichent correctement en mode draft
  4. Tester le fallback content collections

    • Si des posts Markdown existent dans src/content/blog/, naviguer vers un de ces posts
    • Vérifier que le post Markdown s’affiche correctement (fallback)
    • Vérifier qu’il n’y a pas de conflit avec les posts Sanity
  • ✅ Chaque URL affiche le document principal correspondant dans le panneau “Documents on this page”
  • ✅ Les documents de type page sont correctement mappés aux URLs /{slug}
  • ✅ Les documents de type amn sont correctement mappés à l’URL /welcome
  • ✅ Les documents de type post sont correctement mappés aux URLs /blog/{slug}
  • ✅ Le clic sur un document dans le panneau navigue vers le document correspondant dans le Studio
  • ✅ Les documents draft sont correctement prévisualisés
  • ✅ Le mode edit s’active automatiquement lors de la prévisualisation d’un draft
  • ✅ Les modifications draft apparaissent en temps réel dans la prévisualisation
  • ✅ Le cookie sanity-preview-perspective est correctement défini
  • ✅ L’endpoint /api/draft-mode/enable valide correctement le secret généré par le Presentation Tool
  • ✅ Les posts Sanity affichent correctement la mainImage
  • ✅ Les posts Sanity affichent correctement l’image de l’author
  • ✅ Les images dans le Portable Text (_type == "image") s’affichent correctement
  • ✅ Les posts draft affichent toutes les images correctement
  • ✅ Le fallback vers les content collections Markdown fonctionne
  • ✅ Aucun conflit de route entre Sanity posts et Markdown posts

Si tous les tests passent :

  • ✅ La configuration mainDocuments fonctionne correctement
  • ✅ Le Presentation Tool peut détecter et afficher les documents appropriés pour chaque page
  • ✅ Le draft mode fonctionne correctement avec les secrets dynamiques
  • ✅ La configuration CORS permet la communication cross-origin
  • ✅ Les éditeurs peuvent prévisualiser et modifier les documents draft en temps réel
  • ✅ Les images des posts Sanity (mainImage, author.image) s’affichent correctement
  • ✅ Les images dans le Portable Text s’affichent correctement
  • ✅ Le fallback vers les content collections Markdown fonctionne sans conflit
  • La configuration mainDocuments utilise defineDocuments de sanity/presentation
  • Les filtres GROQ permettent de mapper les patterns d’URL aux documents Sanity
  • Les paramètres de route (:slug) sont automatiquement passés aux filtres GROQ
  • Le Presentation Tool génère dynamiquement des secrets pour sécuriser le draft mode
  • La configuration allowOrigins est nécessaire pour la communication cross-origin
  • L’endpoint /api/draft-mode/enable utilise validatePreviewUrl pour valider les secrets
  • Le secret est stocké temporairement dans Sanity et expire après 1 heure