Pourquoi un Headless CMS plutôt qu’un CMS ? 

 

Lorsque vous souhaitez mettre en place votre site web, que vous soyez une start-up, une TPE ou une très grosse entreprise, on s’oriente souvent vers une solution clé en main comme les CMS Wordpress, Jahia, Plone, Ionos, …

Il est vrai qu’en peu de temps, vous aurez un site développé et disponible sur le web rapidement, reprenant tous les aspects et les outils pour rendre populaire votre site.

 

1. Un CMS c’est quoi ? 

 

Un CMS (Content Management Service) est un outil permettant le management d'un site web, en pilotant le contenu, mais aussi la partie UI / Design de celui-ci.

Comment est-il composé ? 

 

  1. Architecture Monolithique : Dans un CMS traditionnel, le frontend (interface utilisateur) et le backend (logique métier et base de données) sont étroitement liés, formant une architecture monolithique.
  2. Interface Utilisateur Intégrée : Les CMS traditionnels fournissent une interface utilisateur intégrée qui permet aux utilisateurs de créer, gérer et publier du contenu sans avoir besoin de compétences techniques.
  3. Présentation Prédéfinie : Les CMS traditionnels offrent souvent des thèmes et des modèles prédéfinis pour la conception de sites web, ce qui facilite la création de sites esthétiquement attrayants, mais peut limiter la personnalisation.
  4. Fonctionnalités Intégrées : Les CMS traditionnels proposent généralement une gamme étendue de fonctionnalités intégrées telles que la gestion des utilisateurs, le SEO, le commerce électronique, etc.
  5. Moins de Flexibilité : En raison de leur architecture monolithique, les CMS traditionnels offrent moins de flexibilité en termes de choix de technologies et d'expérience utilisateur.

 

2. Qu’est ce qui peut être bloquant ? 

Lorsque votre produit ou votre entreprise prospère et que vous souhaitez partager vos contenus, vos produits ou encore pousser du contenu sur d’autres plateformes vous allez commencer à être contraint par le produit initial.

Prenons un exemple, je souhaite diffuser un nouveau produit sur mon site web, mais en même temps poster cette information sur les réseaux sociaux, et pourquoi pas le rendre disponible sur une application mobile en notifiant les utilisateurs.

Peu, voir pas de produit CMS vous offrira cette mécanique répondant à votre besoin.

Quelle solution puis-je donc mettre en place, en gardant la mécanique de contribution ? Regardons du côté des Headless CMS.

 

3. Le Headless CMS

Le Headless CMS, se concentre sur la gestion du contenu, tout en offrant une ultra personnalisation.

Il est défini par :

  1. Architecture Découplée : Dans une solution CMS headless, le frontend et le backend sont dissociés, permettant aux développeurs de choisir les technologies les mieux adaptées à chaque couche.
  2. Aucune Interface Utilisateur Intégrée : Les CMS headless ne fournissent pas d'interface utilisateur intégrée, laissant aux développeurs la responsabilité de créer des interfaces utilisateur personnalisées.
  3. Flexibilité Maximale : Les CMS headless offrent une flexibilité maximale en termes de conception de l'interface utilisateur, de gestion du contenu et d'intégration avec d'autres technologies.
  4. Meilleure Séparation des Responsabilités : En séparant le frontend du backend, les CMS headless permettent une meilleure séparation des responsabilités entre les équipes de développement et de contenu.
  5. Idéal pour les Applications Modernes : Les CMS headless sont particulièrement adaptés aux applications web et mobiles modernes nécessitant une expérience utilisateur personnalisée et des performances optimisées.

Grâce à cette technologie, vous serez donc plus flexible et vous pourrez répondre à tous vos besoins.

Cependant, il faudra investir vers une autre technologie pour le frontend de votre application pour compenser la disponibilité d'une interface web intégré.

On vous propose donc de vous expliquer comment migrer ou commencer sur une solution Headless CMS avec la solution Strapi.

 

Comment commencer ou migrer vers un Headless CMS ? 

1. Les technologies

Pour commencer, il faut choisir les technologies.

Aujourd’hui, nous choisissons de vous proposer les technologies suivantes : 

Strapi.full.logo.dark.svg      nextjs-icon-2048x1234-pqycciiu.png

  • Strapi : Headless CMS open source qui permet de créer, gérer et diffuser facilement du contenu sur n’importe quelle plateforme via un système d'API. Il offre une IHM user-friendly ainsi que des plugins pour vous faciliter vos développements. Il vous permet aussi une hyper personnalisation pour répondre à vos propres besoins.
  • React & NextJS :  Solution open source ultra performante pour votre site web & référencement SEO.

 

Le seul prérequis pour commencer, est d'installer NodeJS pour pouvoir exécuter les commandes suivantes.

2. Gérer et publier le contenu 

 

Nous allons dans ce chapitre, installer Strapi afin de gérer et de publier du contenu sur une API pour pouvoir l'exploiter sur votre plateforme de diffusion.

 

Étape 1 : Installation de Strapi

  • Commencer par installer Strapi en utilisant npm (Node Package Manager) :
npx create-strapi-app@latest my-project
  • Suiver les instructions du prompt pour configurer votre projet Strapi.

Puis installer les packages dans le projet

cd my-project && yarn i
cd my-project && npm i

 

Étape 2 : Exécuter le projet

  • Exécuter le build du projet, puis lancer la commande ci-dessous pour déployer le projet en local
yarn build
yarn develop

 

Etape 3

Connecter vous sur : http://localhost:1337/ et créer le compte administrateur via le formulaire


 image4.png

 

Étape 4 : Création d’un bloc de contenu

 

Depuis la page Web, accéder au menu Content-Type-Builder


image5.png

 

Ensuite, créer un nouveau type de contenu pour stocker vos données. 

Choisisser de créer une collection ou un single type. 

  • La collection à plus vocation à créer une liste de contenu exploitable ou par exemple au contenu détail d’une page de votre site, comme par exemple un “Article”
  • Le single type est plus orienté à un contenu unique, comme le contenu d’une home page ou une page parent (par exemple la page du blog qui référence les articles)

Dans notre exemple, nous allons créer des articles. Nous allons donc choisir d'utiliser le type "Collection"

image3.png

 

Ensuite, ajouter des champs correspondant à la structure de données de votre article. Ici on choisira un titre, un slug, une image et un rich text (voir ci-dessous).


image2.png

 

Puis, cliquer sur “Save”, le serveur devra redémarrer.

Étape 5 : Ajouter du contenu.

Sélectionner le menu “Content Manager”, vous devriez retrouver parmi la liste des éléments votre collection “Article”.

Cliquer sur le bouton “Create new Entry” .


Remplisser les champs de votre article , puis cliquer sur “Save”, ensuite n’oubliez pas de cliquer sur le bouton “Publish” afin de rendre disponible votre contenu.

 

Etape 6

 

Maintenant que votre contenu est présent, il faut le rendre disponible. Cliquer dans le menu : “Settings”, puis le sous menu “Roles” de la section Users & Permissions plugin.

Ici nous retrouvons 2 options : 

  • Authenticated :  Les API accessibles de manière authentifié, ce qui veut dire que l’utilisateur requière une connexion SSO compatible avec Strapi (Ceci ce paramètre dans l’onglet “Providers”)
  • Public : Définis les API accessibles en public

Une autre option est possible, l’API Token. Celle-ci se configure dans le sous-menu API Token est permet de définir les API utilisables par Jeton API (utilisation d'un bearer token pour réaliser un call API).

Dans notre cas, nous allons effectuer le test avec des données exposées en public.

Cliquer sur “public”, puis ouvrer le panel “Article”. Vous retrouvez l’ensemble des API par défaut disponible. Sélectionner la méthode find et findOne.


image7.png
 

Cliquer ensuite sur “Save”.

Vous pouvez dès à présent accéder à vos données depuis l’URL : http://localhost:1337/api/articles

Il est temps maintenant de connecter votre nouveau site au contenu de Strapi.

 

Créer un site web et connecter le à Strapi

 

Nous proposons d'utiliser React et NextJS pour migrer votre site.

NextJS est un framework permettant de simplifier le développement et le déploiement de votre site. Très populaire, il est principalement utilisé pour construire des applications web avec un rendu serveur (SSR) ou générer un site statique (SSG).

Très performant, il sera idéal pour vos sites vitrines. 

Pour en savoir plus : https://nextjs.org/

 

Etape 1 : Installer NextJS et créer son projet

 

Créer un nouveau projet Next.js en utilisant "create-next-app"

npx create-next-app nom-du-projet

Accéder au répertoire de votre projet Next.js :

cd nom-du-projet

Etape 2 : Configuration de Next.js pour Accéder à l'API Strapi

  • Installer le module Axios pour effectuer des requêtes HTTP depuis Next.js :
npm install axios
  • Utiliser Axios pour interroger les API Strapi depuis votre application Next.js.
     

Étape 3 : Création du Frontend avec Next.js

  • Tout d'abord, nous allons ajouter un fichier qui implémente l'appel API vers Strapi. Créer un dossier “utils” à la racine, puis un fichier api.tsx. Ajouter le contenu ci dessous.
import axios, { AxiosResponse } from 'axios';

interface Response {
  data: Article[];
}

interface Article {
  id: number;
  title: string;
  picture: any;
  description: string;
}

// Définir l'URL de l'API
const apiUrl = 'http://localhost:1337/api/articles';

// Fonction pour récupérer les utilisateurs depuis l'API
export async function fetchArticles(): Promise<Article[]> {
  try {
    // Effectuer la requête GET à l'URL de l'API
    const response: AxiosResponse<Response> = await axios.get(apiUrl + '?populate=*');

    // Retourner les données de la réponse
    return response.data.data;
  } catch (error) {
    // Gérer les erreurs ici
    console.error('Erreur lors de la récupération des utilisateurs :', error);
    // Retourner une liste vide en cas d'erreur
    return [];
  }
}
  • Ensuite, nous allons ajouter la partie design de notre site, ici on va implémenter des Cards d'article pour chaque article publié dans Strapi. Pour cela copier le code ci-dessous et modifier le fichier page.tsx.
"use client"; // require to use hook useEffect in parent component , see more on nextjs

import { fetchArticles } from "@/utils/api";
import Image from "next/image";
import { useEffect, useState } from "react";

export default function Home() {
  const [articles, setArticles]: any[] = useState([]);
  const STRAPI_URL = "http://localhost:1337";

  useEffect(() => {
  	// Fetch all articles
    const getArticles = async () => {
      try {
        const fetchedArticles = await fetchArticles();
        console.log("List", fetchedArticles);
        setArticles(fetchedArticles);
      } catch (error) {
        console.error("Erreur lors de la récupération des utilisateurs :", error);
      }
    };
    getArticles();
  }, []);

  return (
    <body>
      <header>
        <Image className="relative dark:drop-shadow-[0_0_0.3rem_#ffffff70] dark:invert" src="https://strapi-homol.capfi.fr/next.svg" alt="Next.js Logo" width={180} height={37} priority />
      </header>
      <main className="flex min-h-screen flex-col items-center justify-between p-24">
        <div className="container">
          {articles.map((article: any) => (
            <div className="card" key={article.attributes.id}>
              <h2>{article.attributes.title}</h2>
              <Image alt="" src={STRAPI_URL + article.attributes.picture?.data.attributes.url} width={200} height={200}></Image>
              <p>
                {article.attributes.contents?.map((c: any, index: number) => c.children.map((child: any, i: number) => (index <= 2 ? c.type === "heading" ? <h3 key={i}>{child.text}</h3> : <div key={i}>{child.text}</div> : <></>)))}
                {article.attributes.contents.length > 2 && <a>Show More</a>}
              </p>
            </div>
          ))}
        </div>
      </main>
    </body>
  );
}
  • Afin de lire vos images sur le localhost, on va ajouter un “loader” custom requis par NextJS. Créer un fichier utils/loader.tsx, et ajouter le code suivant : 
export default function imageStrapiLoader({ src, width, quality }: any) {
    return `${src}?w=${width}&q=${quality || 75}`
}
  • Ensuite modifier le fichier de configuration de NextJS permettant l'implémentation de ce loader. Modifier le fichier “next.config.tsx” ou “next.config.mjs” par le code ci-dessous :
/** @type {import('next').NextConfig} */
const nextConfig = {
	images: {
		loader: "custom",
		loaderFile: "./utils/loader.tsx",
		domains: process.env.CORS?.split(",") || ["localhost"],
	  },
};

export default nextConfig;
  • Enfin, pour ajouter un peu de design, modifier le fichier “globals.css” avec le code ci-dessous : 

@tailwind base;
@tailwind components;
@tailwind utilities;

:root {
  --foreground-rgb: 0, 0, 0;
  --background-start-rgb: 214, 219, 220;
  --background-end-rgb: 255, 255, 255;
}

@media (prefers-color-scheme: dark) {
  :root {
    --foreground-rgb: 255, 255, 255;
    --background-start-rgb: 0, 0, 0;
    --background-end-rgb: 0, 0, 0;
  }
}

body {
  color: rgb(var(--foreground-rgb));
  background: linear-gradient(
      to bottom,
      transparent,
      rgb(var(--background-end-rgb))
    )
    rgb(var(--background-start-rgb));
}

@layer utilities {
  .text-balance {
    text-wrap: balance;
  }
}



header {
  display: flex;
  justify-content: flex-start;
  height: 80px;
  position: fixed;
  top: 0;
  width: 100%;
  z-index: 100;
  box-shadow: 0 3px 6px rgba(0, 0, 0, .161);

  img {
    padding: 10px;
  }
}

.container {
  display: flex;
  justify-content: flex-start;
}

.card {
  gap: 1em;
  padding: 10px;
  margin: 10px;
  width: 33%;
  display: flex;
  flex-direction: column;
  align-items: center;
  box-shadow: 0 3px 6px rgba(0, 0, 0, .161);
  

  h2 {
    font-weight: bold;
    padding : 10px;

  }

  p {
    display: flex;
    justify-content: center;
    flex-direction: column;
    padding: 30px 30px;

    a {
      padding: 10px;
      color: blue;
      cursor: pointer;
    }
    h3 {
      padding: 10px;
      font-weight: bold;
    }

    div {
      padding: 10px
    }
  }
}
  • Il vous suffit ensuite de lancer la commande suivante pour lancer votre site en local.
npm run dev

WebSite.PNG

 

Voilà, vous avez pu connecter votre site avec votre contenu dans Strapi. Il est temps pour vous de commencer ou migrer votre site vers cette solution.

 

Conclusion

 

Nous avons pu voir à travers de cet article qu'il est très simple de mettre en place la base d'un site web en SSR avec une solution Headless CMS.  Et vous vous rendrez compte, qu'avec cette base, il sera facile de managé du contenu sur un système , peu importe la plateforme qui l'exploite, tout en sécurisant ces données grâce aux rôles et jetons d'accès.

De plus l'outil, permet un management fin des droits sur le contenu, ce qui peut répondre aux enjeux de management des droits pour votre entreprise.

Beaucoup d'autres aspects ne sont pas explorés ici, comme la génération d'un site statique, la diffusion de contenu sécurisé, la mise à jour du site via WebHook et usine DevOps (Git, Azure Devops, Jenkins, …), etc… 

Il ne vous reste plus qu'à explorer les faisabilités des outils pour répondre à vos besoins.

 

Bonus

Voici quelques plugins que Strapi diffuse dans son marketplace qui me semble être utile pour le déploiement de votre site sur le web.

Retrouver les sur le marketplaces de Strapi.