Comment utiliser MDX stocké dans Sanity dans un site Web Next.js
MDX vous offre l'ergonomie minimaliste de Markdown avec la flexibilité des composants personnalisés. En combinant MDX avec Sanity et Next, vous pouvez créer des expériences d'édition de contenu robustes et conviviales tout en conservant l'expérience de développeur agréable et efficace de la création de sites Jamstack avec React.
Récemment, mon équipe a entrepris un projet de création d'un site Web, plateforme d'apprentissage basée sur la vidéo. Le projet, appelé Jamstack Explorers est une application Jamstack alimentée par Sanity et Next.js. Nous savions que le succès de ce projet reposait sur le fait de rendre l'expérience d'édition facile pour les collaborateurs de différentes sociétés et rôles, ainsi que de conserver la flexibilité d'ajouter des composants personnalisés si nécessaire.
Le site Jamstack Explorers alimenté par Next.js, Sanity et MDX. ( Grand aperçu )
Pour ce faire, nous avons décidé de créer du contenu en utilisant MDX qui est Markdown avec l'option d'inclure des composants personnalisés. Pour notre public, Markdown est une approche standard de la rédaction de contenu: c'est la façon dont nous formalisons les commentaires GitHub, les documents Notion, les messages Slack (un peu) et de nombreux autres outils. Les composants MDX personnalisés sont facultatifs et leur utilisation est similaire aux codes courts dans WordPress et dans les langages de création de modèles.
Pour permettre de collaborer avec des contributeurs de n'importe où, nous avons décidé d'utiliser Sanity comme système de gestion de contenu ( CMS).
Mais comment pourrions-nous écrire MDX dans Sanity? Dans ce didacticiel, nous allons expliquer comment nous configurons le support MDX dans Sanity, et comment charger et rendre ce MDX dans le site Web Next.js en utilisant un exemple réduit.
TL; DR
Si vous voulez accéder directement aux résultats, voici quelques liens utiles:
Comment écrire du contenu avec MDX In Sanity
Notre première étape consiste à configurer notre flux de travail de gestion de contenu. Dans cette section, nous allons passer en revue la configuration d'une nouvelle instance Sanity, l'ajout de la prise en charge de l'écriture de MDX et la création d'une API publique en lecture seule que nous pouvons utiliser pour charger notre contenu dans un site Web à des fins d'affichage.
Create A Nouvelle instance Sanity
Si vous n'avez pas déjà configuré d'instance Sanity, commençons par cela. Si vous avez déjà une instance Sanity, passez à la section suivante.
Notre première étape consiste à installer la CLI Sanity globalement, ce qui nous permet d'installer, de configurer et d'exécuter Sanity localement. [19659015] # installer la CLI Sanity npm i -g @ sanity / cli
Dans votre dossier de projet, créez un nouveau répertoire appelé sanity, déplacez-vous dedans et exécutez la commande init de Sanity pour créer un nouveau projet.
# créer un nouveau répertoire contenant les fichiers Sanity
mkdir raison
cd sanity /
sanity init
La commande init posera une série de questions. Vous pouvez choisir tout ce qui a du sens pour votre projet, mais dans cet exemple, nous utiliserons les options suivantes:
Choisissez un nom de projet: Sanity Next MDX Example.
Choisissez la configuration de jeu de données par défaut («production»). [19659020] Utilise le chemin de sortie du projet par défaut (le répertoire courant).
Choisissez «nettoyer le projet» parmi les options du modèle.
Cette commande installera le plugin et ajoutera la configuration appropriée à votre instance Sanity pour la rendre utilisable.
Définir un schéma personnalisé avec une entrée Markdown
Dans Sanity, nous contrôlons chaque type de contenu et entrée en utilisant des schémas . C'est l'une de mes fonctionnalités préférées à propos de Sanity, car cela signifie que j'ai un contrôle précis sur ce que chaque type de contenu stocke, comment ce contenu est traité et même comment l'aperçu du contenu est construit.
Pour cet exemple, nous vous allez créer une structure de page simple avec un titre, un slug à utiliser dans l'URL de la page et une zone de contenu qui attend Markdown.
Créez ce schéma en ajoutant un nouveau fichier à sanity / schemas / page.js et en ajoutant le code suivant:
Nous commençons par donner à tout le type de contenu un nom et un titre. Le type de document indique à Sanity qu'il doit être affiché au niveau supérieur de Sanity Studio en tant que type de contenu que quelqu'un peut créer.
Chaque champ a également besoin d'un nom, d'un titre et d'un type. Nous pouvons éventuellement fournir des règles de validation et d'autres options, comme donner au slug une longueur maximale et lui permettre d'être généré à partir de la valeur du titre.
Ajouter un schéma personnalisé à la configuration de Sanity
Après notre schéma est défini, nous devons dire à Sanity de l'utiliser. Nous le faisons en important le schéma dans sanity / schemas / schema.js puis en l'ajoutant au tableau types passé à createSchema .
// Tout d'abord, nous devons importer le créateur de schéma
importez createSchema depuis 'part: @ sanity / base / schema-creator';
// Ensuite, importez les types de schémas à partir de tous les plugins susceptibles de les exposer
import schemaTypes de 'all: part: @ sanity / base / schema-type';
+ // Importez des types de schémas personnalisés ici
+ importer la page depuis './page';
// Ensuite, nous donnons notre schéma au constructeur et fournissons le résultat à Sanity
exporter par défaut createSchema ({
// Nous nommons notre schéma
nom: 'default',
// Procédez ensuite à la concaténation de notre type de document
// à ceux fournis par les plugins installés
types: schemaTypes.concat ([
- /* Your types here! */
+ page,
]),
});
Cela place notre schéma de page dans la configuration de démarrage de Sanity, ce qui signifie que nous pourrons créer des pages une fois que nous aurons démarré Sanity!
Exécutez Sanity Studio localement
Maintenant que nous avons défini un schéma et configuré, nous pouvons démarrer Sanity localement.
sanity start
Une fois qu'il est en cours d'exécution, nous pouvons ouvrir Sanity Studio à http: // localhost: 3333 sur notre machine locale.
Lors de notre visite cette URL, nous devrons nous connecter la première fois. Utilisez votre compte préféré (par exemple, GitHub) pour vous authentifier. Une fois connecté, vous verrez le tableau de bord Studio, qui semble assez simple.
Pour ajouter une nouvelle page, cliquez sur "Page", puis sur l'icône en forme de crayon en haut à gauche.
Ajoutez un titre et un slug, puis écrivez un Markdown avec MDX dans la zone de contenu:
Ceci est écrit en [Markdown] (https://www.markdownguide.org/basic-syntax/).
Mais qu'est-ce que c'est?
Oh dang! Est-ce un composant React au milieu de notre contenu? 😱
Seaux saints! C’est incroyable!
Attention! La ligne vide entre le composant MDX et le Markdown qu'il contient est obligatoire. Sinon, le Markdown ne sera pas analysé. Ce sera corrigé dans MDX v2 .
Une fois le contenu en place, cliquez sur "Publier" pour le rendre disponible.
Déployez The Sanity Studio vers une URL de production
Pour apporter des modifications à les données du site sans avoir à exécuter le code localement, nous devons déployer le Sanity Studio. La CLI Sanity rend cela possible avec une seule commande:
sanity deploy
Choisissez un nom d'hôte pour le site, qui sera utilisé dans l'URL. Après cela, il sera déployé et accessible via votre propre lien personnalisé.
Sortie du terminal après le déploiement de Sanity Studio à l'aide de la CLI. ( Grand aperçu )
Ceci fournit une URL de production permettant aux éditeurs de contenu de se connecter et d'apporter des modifications au contenu du site.
Rendre le contenu Sanity disponible via GraphQL
Sanity est livré avec le support de GraphQL , que nous utiliserons pour charger nos données de page dans le front-end de notre site. Pour cela, nous devons déployer une API GraphQL, qui est un autre one-liner:
sanity graphql deploy
Nous pouvons choisir d'activer un GraphQL Playground, ce qui nous donne un explorateur de données basé sur un navigateur. Ceci est extrêmement pratique pour tester les requêtes.
Sortie du terminal après le déploiement de l'API GraphQL à l'aide de la CLI de Sanity. ( Grand aperçu )
Stockez l'URL GraphQL – vous en aurez besoin pour charger les données dans Next.js!
https://sqqecrvt.api.sanity.io/v1/graphql / production / default
L'API GraphQL est en lecture seule pour le contenu publié par défaut, nous n'avons donc pas à nous soucier de garder ce secret – tout ce que cette API renvoie est publié, ce qui signifie que c'est ce que nous voulons que les gens voient
Tester les requêtes GraphQL Sanity dans le navigateur
En ouvrant l'URL de notre API GraphQL, nous pouvons tester les requêtes GraphQL pour nous assurer d'obtenir les données attendues. Ces requêtes peuvent être copiées dans notre code.
Pour charger nos données de page, nous pouvons créer la requête suivante en utilisant l'onglet «schéma» sur le côté droit comme référence.
Cette requête charge toutes les pages publiées dans Sanity, renvoyant le titre, le slug actuel et le contenu de chacune. Si nous exécutons ceci dans la cour de récréation en appuyant sur le bouton de lecture, nous pouvons voir notre page retournée.
Sanity est livré avec un GraphQL Playground intégré pour tester les requêtes dans le navigateur. ( Grand aperçu )
Maintenant que nous avons des données de page avec MDX en retour de Sanity, nous sommes prêts à créer un site en l'utilisant!
Dans la section suivante, nous va créer un site Next.js qui charge les données de Sanity et rend notre contenu MDX correctement.
Afficher MDX dans Next.js From Sanity
Dans un répertoire vide, commencez par initialiser un nouveau package.json puis installez Next, React et un package appelé next-mdx-remote .
# crée un nouveau package.json avec les options par défaut
npm init -y
# installer les packages dont nous avons besoin pour ce projet
npm i next react react-dom next-mdx-remote
Dans package.json ajoutez un script à exécuter next dev :
Créer des composants React à utiliser dans le contenu MDX
Dans le contenu de notre page, nous avons utilisé le composant pour encapsuler certains de nos Markdown. MDX fonctionne en combinant les composants React avec Markdown, ce qui signifie que notre première étape est de définir le composant React que notre MDX attend.
Créez un composant Callout à src / components / callout.js :
export Callout de fonction par défaut ({enfants}) {
revenir (
{enfants}
);
}
Ce composant ajoute une boîte bleue autour du contenu que nous souhaitons attirer l'attention.
Envoyer des requêtes GraphQL à l'aide de l'API Fetch
Cela n'est peut-être pas évident, mais vous n'avez pas besoin d'une bibliothèque spéciale pour envoyer des requêtes GraphQL! Il est possible d'envoyer une requête à une API GraphQL en utilisant l'API Fetch intégrée du navigateur .
Puisque nous allons envoyer quelques requêtes GraphQL sur notre site, ajoutons une fonction utilitaire qui gère cela donc nous n'avons pas à dupliquer ce code dans un tas d'endroits.
Ajoutez une fonction utilitaire pour récupérer les données Sanity en utilisant l'API Fetch à src / utils / sanity.js :
Le premier argument est l'URL Sanity GraphQL que Sanity a renvoyée lorsque nous avons déployé l'API GraphQL.
Les requêtes GraphQL sont toujours envoyées à l'aide de la méthode POST et de l'application / json ] en-tête de type de contenu.
Le corps d'une requête GraphQL est un objet JSON stringifié avec deux propriétés: query, qui contient la requête que nous voulons exécuter sous forme de chaîne; et variables, qui est un objet contenant toutes les variables de requête que nous voulons transmettre à la requête GraphQL.
La réponse sera JSON, nous devons donc gérer cela dans le . puis pour le résultat de la requête, puis nous pouvons déstructurer le résultat pour accéder aux données à l'intérieur. Dans une application de production, nous souhaitons également rechercher les erreurs dans le résultat et afficher ces erreurs de manière utile, mais il s'agit d'un article sur MDX, pas sur GraphQL, donc #yolo.
Attention! L'API Fetch est idéale pour les cas d'utilisation simples, mais à mesure que votre application devient plus complexe, vous voudrez probablement examiner les avantages de l'utilisation d'un outil spécifique à GraphQL comme Apollo ou urql .
Créer une liste de toutes les pages de Sanity dans Next.js
Pour commencer, faisons une liste de toutes les pages publiées dans Sanity, ainsi qu'un lien vers leur slug (qui ne fonctionnera pas encore ).
Créez un nouveau fichier à src / pages / index.js et mettez le code suivant à l'intérieur:
import Link from 'next / link';
import {getSanityContent} depuis '../utils/sanity';
Exporter l'index de la fonction par défaut ({pages}) {
revenir (
Ce site charge MDX à partir de Sanity.io
Consultez l'une de ces pages pour le voir en action:
Dans getStaticProps nous appelons l'utilitaire getSanityContent avec une requête qui charge le titre et le slug de toutes les pages de Sanity. Nous mappons ensuite les données de la page pour créer un objet simplifié avec une propriété title et slug pour chaque page et renvoyons ce tableau en tant que page prop.
Le composant Index pour afficher cette page reçoit le prop de cette page, donc nous mappons sur cela pour afficher une liste non ordonnée de liens vers les pages.
Démarrez le site avec npm run dev et ouvrez http: // localhost: 3000 pour voir le travail en cours.
L'utilisation de getStaticProps signifie que cette page fonctionnera également sans l'activation de JavaScript! ( Grand aperçu )
Si nous cliquons maintenant sur un lien de page, nous obtiendrons une erreur 404. Dans la section suivante, nous allons résoudre ce problème!
Générer des pages par programme dans Next.js à partir de données CMS
Next.js prend en charge routes dynamiques donc configurons un nouveau fichier pour capturer toutes les pages sauf notre page d'accueil à src / pages / [page] .js .
Dans ce fichier, nous devons indiquer à Next quels sont les slugs dont il a besoin pour générer en utilisant le getStaticPaths ].
Pour charger le contenu statique de ces pages, nous devons utiliser getStaticProps qui recevra le slug de page actuel dans params.page.
Pour aider à visualiser ce qui se passe, nous ' Je vais passer le slug à notre page et déconnecter les accessoires à l'écran pour le moment.
import {getSanityContent} from '../utils/sanity';
Exporter la page des fonctions par défaut (accessoires) {
return
{JSON.stringify (props, null, 2)}
; }
Exporter la fonction asynchrone getStaticProps ({params}) { revenir { accessoires: { slug: page paramètres, }, }; }
Exporter la fonction asynchrone getStaticPaths () { const data = attendre getSanityContent ({ requête: ` query AllPages { allPage { limace { courant } } } `, });
Si le serveur est déjà en cours d'exécution, il se rechargera automatiquement. Sinon, exécutez npm run dev et cliquez sur l'un des liens de page sur http: // localhost: 3000 pour voir l'itinéraire dynamique en action.
Charger les données de la page de Sanity pour le slug de la page actuelle dans Next.js
Maintenant que nous avons le slug de page, nous peut envoyer une requête à Sanity pour charger le contenu de cette page.
En utilisant la fonction utilitaire getSanityContent envoyez une requête qui charge la page actuelle en utilisant son slug, puis extrayez uniquement les données de la page et retournez que dans les accessoires.
Rendu MDX à partir d'un CMS dans Next.js avec Next-mdx-remote
Pour rendre le MDX, nous devons effectuer deux étapes:
Pour le build- traitement temporel de MDX, nous devons rendre le MDX en une chaîne. Cela transformera le Markdown en HTML et garantira que les composants React sont exécutables. Cela se fait en passant le contenu sous forme de chaîne dans renderToString avec un objet contenant les composants React que nous voulons être disponibles dans le contenu MDX.
Pour le rendu côté client de MDX, nous hydratons le MDX en passant la chaîne rendue et les composants React. Cela rend les composants disponibles pour le navigateur et déverrouille l'interactivité et les fonctionnalités React.
Bien que cela puisse donner l'impression de faire le travail deux fois, ce sont deux processus distincts qui nous permettent à la fois de créer un balisage HTML entièrement rendu qui fonctionne sans JavaScript activé et fonctionnalité dynamique côté client fournie par JavaScript.
Apportez les modifications suivantes à src / pages / [page] .js pour rendre et hydrater MDX:
+ import hydrate from 'next-mdx -à distance / hydrate »;
+ importer renderToString à partir de 'next-mdx-remote / render-to-string';
import {getSanityContent} de '../utils/sanity';
+ importer la légende depuis '../components/callout';
- Exporter la page des fonctions par défaut (accessoires) {
- return
Après avoir enregistré ces modifications, rechargez le navigateur et nous pouvons voir le contenu de la page rendu correctement, les composants React personnalisés et tout!
Le composant personnalisé apparaîtra avec et sans JavaScript activé! ( Grand aperçu )
Utilisez MDX avec Sanity et Next.js pour les flux de travail de contenu flexible
Maintenant que ce code est configuré, les éditeurs de contenu peuvent rapidement écrire du contenu à l'aide de MDX pour activer la vitesse de Markdown avec la flexibilité des composants React personnalisés, tous de Sanity! Le site est configuré pour générer toutes les pages publiées dans Sanity, donc à moins que nous ne voulions ajouter de nouveaux composants personnalisés, nous n'avons pas du tout besoin de toucher au code Next.js pour publier de nouvelles pages.
Ce que j'aime à ce sujet workflow, c'est qu'il me permet de conserver mes parties préférées de plusieurs outils: j'aime beaucoup écrire du contenu dans Markdown, mais mon contenu a également besoin de plus de flexibilité que la syntaxe standard de Markdown ne le fournit; J'aime créer des sites Web avec React, mais je n'aime pas gérer du contenu dans Git.
Au-delà de cela, j'ai également accès à l'énorme quantité de personnalisations disponibles dans les écosystèmes Sanity et React, ce qui donne l'impression d'avoir mon gâteau et le manger aussi.
Si vous recherchez un nouveau flux de travail de gestion de contenu, j'espère que vous apprécierez celui-ci autant que moi!
Et maintenant?
Maintenant que vous avez un Suivant site utilisant MDX de Sanity, vous voudrez peut-être aller plus loin avec ces didacticiels et ressources: