Créer son site avec Gatsby et Prismic

Retrouvez l'ensemble du code source utilisé pour faire ce tutorial sur ce dépôt github

Gatsby est un framework javascript permettant la création de site web statique en React de manière simple. Gatsby est réputé pour ses performances exceptionnelles. Mais attention c'est le site généré qui est statique, des fichiers HTML/JS simples, le contenu récupéré au préalable pour construire ses pages peut-être quand à lui être dynamique. Nous allons ainsi connecter Gatsby à un C.M.S. headless c'est à dire sans front, mais les C.M.S. headless ne manquent pas. Ma préférence va à Prismic car il dispose d'une feature très intéressante les slices, nous aurons le temps d'y revenir un peu plus tard.

Installer Gatsby

Vous devez au préalable avoir Node d’installer sur votre machine mac, linux, ou windows.
J’utilise actuellement la version 13.7 et npm dans sa version v6. Veillez surtout à avoir au moins la version 9 de Node, Gatsby est en train d'arrêter le support des anciennes versions.
Vous pouvez vérifier que node et npm sont bien installés en utilisant la commande suivante.

$ node -v
v13.10.1
$ npm -v
6.13.7

Node et npm sont installés nous allons pouvoir commencer ! Nous allons commencer par installer Gatsby C.L.I. (command line interface) pour pouvoir installer nos sites rapidement en ligne de commande et se sentir développeur.
Dans votre invite de commande, veuillez saisir :

$ npm install -g gatsby-cli

Gatsby est maintenant installé sur votre machine vous maintenant utiliser tout une série de commande qui commencent toutes par Gatsby. Pour les connaitre vous pouvez toujours taper

$ gatsby -help

Créer son site Gatsby

Placez vous dans le dossier où vous souhaitez installer votre site, par habitude j'ai un dossier www qui contient l'ensemble de mes sites.
Ensuite pour créer votre site ce sera gatsby new [rootpah] [starter]

  • rootpath : c'est le nom du dossier dans lequel vos fichier seront installés. Paramètre optionnel
  • starter : second paramètre optionnel, les starter sont une sorte de thème, ils vont vous aider à démarrer en vous fournissant, un style (un peu à la manière d'un thème WP) et/ou les moyens pour récupérer vos contenus distants (Wordpress, Contentful, Prismic, fichiers markdown). Si vous ne précisez aucun starter. C'est le starter par défaut qui sera installé

C'est ce que nous allons faire, nous utiliserons une installation minimale et ajouterons petit à petit les composants dont nous aurons besoin. Dans votre dossier vous pouvez donc saisir



gatsby new mon_incroyable_site_avec_gatsby

Après quelques minutes votre site devrait être installé ✌️

Une fois le site installé vous pouvez, vous placer dans le dossier créer (pour moi 02-gatsby-blogv2)

cd 02-gatsby-blogv2

Et enfin démarrer votre site avec la commande :

gatsby develop

Je pensais pouvoir sabrer le champagne à ce moment mais c’était sans compter le drame, un petit problème d’installation de module. Pas de panique le problème a été réglé rapidement comme le montre la capture ci dessous, suppression du dossier incriminé et réinstallation.

Ce problème réglé j’ai pu relancer ma commande de démarrage et contempler mon magnifique site.

Architecture d'un site Gatsby

Gatsby est donc un framework React, essayons de voir ensemble son fonctionnement un peu plus en détail.

/
|-- /.cache
|-- /public
|-- /src
|-- /pages
|-- /templates
|-- /static
|-- gatsby-config.js
|-- gatsby-node.js
|-- gatsby-ssr.js
|-- gatsby-browser.js

Dossier /.cache

Généré automatiquement, ce dossier est un cache interne créé de manière automatique par Gatsby. Les fichiers et dossiers à l'intérieur ne sont pas destinés à être modifié. Ce dossier devrait également être ajouté à votre fichier .gitignore si ce n'est pas déjà fait. Si vous souhaitez vider le cache de votre application vous pouvez utiliser la commande suivante.

$ gatsby clean

Dossier /public

C'est un dossier qui sera généré après avoir lancé pour la première fois la commande gatsby build. Attention il est probable que vous obteniez une erreur Mkdir permission denied pour la création du dossier .cache, dans ce cas là, relancer votre invite de commande en tant qu'administrateur.
C'est ce dossier qui va contenir les fichiers générés, c'est ce dossier que l'on déposera sur le serveur pour que le client y accède.
Comme le .cache ce dossier doit être ajouté à votre .gitignore si ce n'est pas déjà le cas.

Dossier /src

Ce dossier va contenir toute la partie frontend de votre site, header, footer, layout, contenu de vos différentes pages. C'est là que vous allez développer vos composants, comme vous le feriez dans n'importe quelle application React.

Dossier /src/pages/

Ici chaque fichier JS qui va contenir un composant React va devenir une page entière du site, pas besoin d'outil de routing . Voici par exemple l'exemple de ma page d'accueil.
Ainsi si vous souhaitez créer une nouvelle page, il vous suffira donc de créer un fichier. Attention à bien nommer le fichier en respectant la convention de nommage kebab-case.
Ainsi si vous créer un fichier galerie.js dans le dossier page qui contient un composant React valide. Cela créera automatiquement une nouvelle page accessible à l'adresse suivante http://localhost:8000/galerie

import React from 'react'

import SEO from '../components/seo'

const IndexPage = () => (
  <>
    <SEO title="Home" />
    <h1>Bienvenue sur le site de Johan Petrikovsky </h1>
    <p>Apprenti développeur compulsif.</p>
    <p>Now go build something great.</p>
  </>
)

export default IndexPage

Dossier /src/templates/

Le dossier template va contenir l'ensemble des pages construites dynamiquement, exemple dans le cadre d'un blog, ce sera l'ensemble des pages avec le détail de vos articles. Le template va donc correspondre à un modèle, et l'ensemble des pages sera construit selon ce modèle.

Fichier /gatsby-node.js

C'est ici que l'on va dire à Gatsby de construire nos pages après avoir récupéré du contenu dynamiquement.

C'était un tour non exhaustif des fichiers et dossiers, pour plus d'informations vous pouvez toujours vous rendre sur la doc officielle.

Prise en main de Prismic

C'est le moment de rendre notre site dynamique. Nous allons commencer par remplacer le contenu de notre page d'accueil par du contenu récupérer dynamiquement sur Prismic. Allez donc sur Prismic.io pour créer un compte et votre premier repository.

Création d'un custom type

Une fois créé votre dépôt devrait apparaître sur la page d'accueil de votre tableau de bord

En accédant à votre dépôt vous allez pouvoir créer votre premier Custom type.
Un Custom type, c'est un mot un peu fourre-tout pour définir les différents éléments que nous allons pouvoir créer. Par défaut chez WordPress vous disposez de pages et d'articles, mais quid si vous souhaitez créer des événements, des annonces etc... vous allez devoir généralement installer des plugins, ou devoir développer les votre ce qui n'est pas toujours simple.
Chez Prismic, nous partons de 0, nous allons créer uniquement ce dont nous avons besoin et de manière extrêmement simple. Que ce soit ici, côté back ou côté front pour récupérer nos données.
Il est à noter que nous avons deux types Repeatable et Single. Pour vous aider à choisir,

  • Si vous avez DES articles, DES produits, DES annonces, ce sera un type répétables.
  • En revanche si vous avez UNE page d'accueil, UNE page contact, ce sera un type single.

Attention aux pièges ! Vous pourriez avoir une page de mentions légales, et une page sur la politique de confidentialité. Mais si le gabarit de ses pages est identique, généralement un titre + un champ de texte long ; ce sera un type répétable, que vous pourriez appeler par exemple page informations.

Comme nous souhaitons toujours remplacer le contenu de notre page d'accueil, sans plus attendre, créons donc un Single Type Homepage.

Lorsque vous créer un nouveau champ, il y a plusieurs informations à saisir :

  • AP ID va correspondre à l'identifiant qui sera utilisé lors de nos requetes graphQL
  • Placeholder, sera plutôt une petite phrase d'indice destiné à la personne qui va saisir le contenu
  • Et enfin le name, qui est simplement le nom de votre champ qui apparaîtra également pendant la saisie.

    Pour notre page d'accueil, j'ai opté pour 4 champs.
  1. Un identifiant unique - uid - de type uid - que j'ai appelé uid. Pas du tout obligatoire, mais j'ai pris l'habitude d'en avoir un pour chacun des types que je créé, on en reparlera plus tard si vous êtes sages.
  2. Un titre de type - title - que j'ai appelé title
  3. Une description de type - Rich text - que j'ai appelé description
  4. Et enfin un champ image que j'ai appelé main_illustration

Pour les flemmards ou si vous souhaitez suivre exactement ce tuto, vous avez la possibilité d'utiliser la même configuration que moi. Pour ce faire copier le code JSON ci-dessous. Pour aller ensuite le coller dans la partie JSON Editor dans la colonne de droite (cf. capture précédente).
Ce JSON Editor peut être très utile pour partager des configurations entre différents projets et créer votre "propre CMS" Vous avez développé un module d'actualité pour un projet, vous pouvez avec ce système le partager avec un autre projet sans problème.
On peut également imaginer la communauté créer des petits "plugins" et les partager facilement.

Nous aurons également besoin de ce fichier un peu plus tard pour faire communiquer Gatsby et Prismic. Sauvegardez donc ce fichier homepage.json dans src/schemas (il faut que votre fichier porte le même nom que votre custom type). Si le dossier n'existe pas, créez le.

{
  "Main" : {
    "uid" : {
      "type" : "UID",
      "config" : {
        "label" : "uid",
        "placeholder" : "uid"
      }
    },
    "title" : {
      "type" : "StructuredText",
      "config" : {
        "single" : "heading1, heading2, heading3, heading4, heading5, heading6",
        "label" : "title",
        "placeholder" : "title"
      }
    },
    "description" : {
      "type" : "StructuredText",
      "config" : {
        "multi" : "paragraph, preformatted, heading2, heading3, heading4, heading5, heading6, strong, em, hyperlink, image, embed, list-item, o-list-item, o-list-item",
        "allowTargetBlank" : true,
        "label" : "description",
        "placeholder" : "description"
      }
    },
    "main_illustration" : {
      "type" : "Image",
      "config" : {
        "constraint" : { },
        "thumbnails" : [ ],
        "label" : "main_illustration"
      }
    }
  }
}

Création du contenu

Nous allons pouvoir créer notre première page. Dans la colonne de gauche de l'interface d'administration accéder au premier élément content, puis create new

Nous pouvons maintenant saisir le contenu de notre page d'accueil. Pour sauvegarder, cela se passe en haut à droite, bouton Save , puis publish pour publier votre contenu. C'est à dire que lorsque vous allez appuyer sur le bouton Save, votre contenu est sauvegardé, mais le build (l'appel du web hook) ne sera pas déclenché.

Lier Gatsby avec Prismic

OK notre back-office est en place, la partie front également, il n'y a plus qu'à connecter les deux. Cela va se faire en deux étapes :

  • Installation du plugin pour récupérer le contenu.
  • Création de notre requête GraphQL.

Installation du plugin gatsby-source-prismic

A la racine de votre projet saisir la commande suivante pour installer votre plugin

$ npm install --save gatsby-source-prismic

Le plugin est installé dans notre dossier node module, pour le faire communiquer avec Gatsby il va falloir éditer notre fichier gatsby-config.js à la racine du projet. et ajouter une entrée à array plugins

// Dans votre fichier gatsby-config.js
plugins: [
    {
      resolve: 'gatsby-source-prismic',
      options: {
        // Le nom de votre dépôt prismic.io. ce champ est obligatoire
        // Example: 'tuto-gatsby' si votre adresse est 'tuto-gatsby.prismic.io'
        repositoryName: 'tuto-gatsby',       
        accessToken: `votre_token_prismic`,
        // Récupérer le fichier json de homepage dans Prismic (Json Editor, cf. plus haut)
        schemas: {
          homepage: require('./src/schemas/homepage.json'),
        },
      },
    },

   // Vos autres plugin....
]

ATTENTION : Le fait d'ajouter notre token ici n'est pas la manière la plus sécurisée, ne poussez pas en l'état votre application sur un dépôt public. Nous verrons plus tard comment sécuriser au mieux notre application.
Le fichier homepage.json correspond au fichier que nous avons créer précédemment au moment de la création de notre custom type.

Si tout s'est bien déroulé, vous devriez avoir accès à l'adresse suivante - http://localhost:8000/___graphql - C'est ici que nous allons pouvoir définir la requête pour récupérer notre contenu, il suffit simplement de sélectionner les champs dans la colonne de gauche et appuyer sur play pour voir si tout s'est bien déroulé

query MyQuery {
  prismicHomepage {
    data {
      description {
        html
      }
      title {
        text
      }
      main_illustration {
        fluid {
          srcWebp
          srcSetWebp
          srcSet
          src
          sizes
          base64
          aspectRatio
        }
      }
    }
  }
}

Ok nous avons notre requête GraphQL, le plus gros du travail est fait il n'y a plus qu'à l'intégrer dans notre page d'accueil. Nous allons donc ouvrir notre fichier index.js et y ajouter la requête

// FICHIER index.js
import React from "react"
// En plus de link on importe graphql
import { Link, graphql } from "gatsby"

import Layout from "../components/layout"
import Image from "../components/image"
import SEO from "../components/seo"

// On ajoute notre props data
// Résultat de notre requête GraphQL
const IndexPage = ({data}) => (
  <Layout>
    {console.log(data)}
    <SEO title="Home" />
    <h1>Hi people</h1>
    <p>Welcome to your new Gatsby site.</p>
    <p>Now go build something great.</p>
    <div style={{ maxWidth: `300px`, marginBottom: `1.45rem` }}>
      <Image />
    </div>
    <Link to="/page-2/">Go to page 2</Link>
  </Layout>
)

// Consommer de la data avec GraphQL
export const pageQuery = graphql`

query MyHomeQuery {
  prismicHomepage {
    id
    data {
      description {
        html
      }
      title {
        text
      }
      main_illustration {
        alt
        copyright
        url
        thumbnails
        fluid {
          srcWebp
          srcSetWebp
          srcSet
          src
          sizes
          base64
          aspectRatio
        }
      }
    }
  }
}
`

export default IndexPage

Si tout s'est bien passé, le console.log devrait retourner un objet avec l'ensemble de nos infos. Il n'y a plus qu'à utiliser cet objet pour afficher les différentes infos.

import React from "react"
import { Link, graphql } from "gatsby"

import Layout from "../components/layout"
// import Image from "../components/image"
// On importe Gatsby image
import Img from 'gatsby-image'
import SEO from "../components/seo"

const IndexPage = ({data}) => (
  <Layout>
    {console.log(data)}
    <SEO title="Home" />
    <h1>{data.prismicHomepage.data.title.text}</h1>
    <div dangerouslySetInnerHTML={{__html: data.prismicHomepage.data.description.html}} />
    <Img
        style={{ maxWidth: '270px' }}
        fluid={data.prismicHomepage.data.main_illustration.fluid}
      />
    <Link to="/page-2/">Go to page 2</Link>
  </Layout>
)

export const pageQuery = graphql`

query MyHomeQuery {
  prismicHomepage {
    id
    data {
      description {
        html
      }
      title {
        text
      }
      main_illustration {
        alt
        copyright
        url
        thumbnails
        fluid{
          srcWebp
          srcSetWebp
          srcSet
          src
          sizes
          base64
          aspectRatio
        }
      }
    }
  }
}
`

export default IndexPage

Ok nous pouvons désormais tester les performances de notre site. Nous allons donc utiliser la commande pour demander à Gatsby de construire nos pages et de nous les servir. L'ajout de -o permet seulement de demander à Gatsby de l'ouvrir directement dans le navigateur.

$ gatsby build
$ gatsby serve -o