Skip to content

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

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

Documentation technique

Contexte

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)

Problèmes identifiés

Problème 1 : Documents non affichés

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.

Problème 2 : Draft mode non fonctionnel

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

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.

Problème 4 : Conflit de route blog

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.

Solutions implémentées

Solution 1 : Configuration mainDocuments

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

  • 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

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")

Solution 4 : Fusion des routes blog

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

Modifications effectuées1/4

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

Modifications effectuées2/4

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

Modifications effectuées3/4

Configuration CORS :

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

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

Modifications effectuées4/4

// 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);
// ...
}

Instructions de test

Prérequis

  1. Les serveurs Astro et Studio doivent être en cours d’exécution
  2. Le mode edit doit être activé dans le Presentation Tool

Étapes de test

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
  1. 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”)
  1. 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
  1. 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
  1. 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

  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)
  1. 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
  1. 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
  1. 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

Test 3 : Blog posts Sanity avec images

  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
  1. 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
  1. 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
  1. 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

Résultats attendus

Test 1 (Documents affichés)

  • ✅ 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

Test 2 (Draft mode)

  • ✅ 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

Test 3 (Blog posts Sanity avec images)

  • ✅ 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

Validation1/2

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

Validation2/2

  • ✅ 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

Notes techniques1/2

  • 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

Notes techniques2/2

  • 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
Switch to normal mode

Contents