Sérialisation du Portable Text
Rendez le contenu Portable Text sur plusieurs frameworks en utilisant la famille de bibliothèques @portabletext/*. Chaque bibliothèque suit le même modèle de mappage de composants : vous fournissez un objet components qui mappe les types de nœuds PT aux renderers spécifiques au framework.
Structure du Portable Text (Référence rapide)
PT est un tableau de blocs. Chaque bloc a _type, un style optionnel, children (spans), markDefs, listItem et level.
Tableau racine
├── block (_type: "block")
│ ├── style: "normal" | "h1" | "h2" | "blockquote" | ...
│ ├── children: [span, span, ...]
│ │ └── span: { _type: "span", text: "...", marks: ["strong", "<markDefKey>"] }
│ ├── markDefs: [{ _key, _type: "link", href: "..." }, ...]
│ ├── listItem: "bullet" | "number" (optionnel)
│ └── level: 1, 2, 3... (optionnel, pour les listes imbriquées)
├── bloc personnalisé (_type: "image" | "code" | tout type personnalisé)
└── ...autres blocs
Les marques existent sous deux formes :
- Décorateurs : valeurs de chaîne dans
marks[]comme"strong","em","underline","code" - Annotations : clés dans
marks[]référençant des entrées dansmarkDefs[](par exemple, liens, références internes)
Modèle de mappage de composants (Tous les frameworks)
Chaque bibliothèque @portabletext/* accepte un objet components avec ces clés :
| Clé | Rend | Props/Données |
|---|---|---|
types |
Types de bloc/inline personnalisés (image, code, CTA) | value (les données du bloc) |
marks |
Décorateurs + annotations | children + value (données de marque) |
block |
Styles de bloc (h1, normal, blockquote) | children |
list |
Wrappers de liste (ul, ol) | children |
listItem |
Éléments de liste | children |
hardBreak |
Sauts de ligne dans un bloc | — |
Règles spécifiques au framework
Consultez le fichier de règles correspondant à votre framework :
- React / Next.js :
rules/react.md—@portabletext/reactounext-sanity - Svelte / SvelteKit :
rules/svelte.md—@portabletext/svelte - Vue / Nuxt :
rules/vue.md—@portabletext/vue - Astro :
rules/astro.md—astro-portabletext - HTML (côté serveur) :
rules/html.md—@portabletext/to-html - Markdown :
rules/markdown.md—@portabletext/markdown - Extraction de texte brut :
rules/plain-text.md—@portabletext/toolkit
Sérialiseurs communautaires supplémentaires
Ceux-ci sont listés sur portabletext.org mais n'ont pas de fichiers de règles dédiés :
| Cible | Paquet |
|---|---|
| React Native | @portabletext/react-native-portabletext |
| React PDF | @portabletext/react-pdf-portabletext |
| Solid | solid-portabletext |
| Qwik | portabletext-qwik |
| Shopify Liquid | portable-text-to-liquid |
| PHP | sanity-php (classe SanityBlockContent) |
| Python | portabletext-html |
| C# / .NET | dotnet-portable-text |
| Dart / Flutter | flutter_sanity_portable_text |
Modèles courants (Tous les frameworks)
Les types personnalisés nécessitent des composants explicites
Les renderers PT ne gèrent que les blocs standard par défaut. Les types personnalisés (image, code, callToAction, etc.) nécessitent des mappages de composants explicites — sinon ils ne seront pas rendus.
Gardez l'objet composants stable
En React/Vue, définissez components en dehors de la fonction de rendu ou memoïzez-le. Le recréer à chaque rendu provoque des re-rendus inutiles.
Gérer les composants manquants avec élégance
Toutes les bibliothèques acceptent onMissingComponent pour contrôler le comportement lors de la rencontre de types inconnus :
false— supprimer les avertissements- Fonction personnalisée — journaliser ou signaler
Interroger PT avec GROQ
Développez toujours les références à l'intérieur des blocs personnalisés :
body[]{
...,
_type == "image" => {
...,
asset->
},
markDefs[]{
...,
_type == "internalLink" => {
...,
"slug": @.reference->slug.current
}
}
}