Blog/Articles/ Comment faire un blog pour son SaaS ?

Comment faire un blog pour son SaaS ?

Comment faire un blog pour son SaaS ?

Tu veux publier gérer un blog sans t’encombrer de CMS complexes ou de plugins mal maintenus ?
Tu veux un système fluide, rapide, et parfaitement intégré à ton SaaS ?
Voici comment j’ai conçu mon propre CMS de contenu pour SaaS Path : une base postgresql modulaire, un éditeur WYSIWYG léger, une navigation intelligente et un SEO poussé pour rank !
Pas de dépendance, pas de surprise, et surtout : un blog qui renforce ton produit, et sa visibilité long terme.

Une base de données simple, pensée pour l’édition, le SEO et la scalabilité

Pourquoi ce modèle ?

Chaque modèle de la base de données a été structuré pour :

  • Éditer facilement un article (titre, image, contenu, FAQ…) ;

  • Stocker les métadonnées SEO dès la création (metaTitle, metaDescription) ;

  • Relier dynamiquement les contenus (catégories multiples, FAQ intégrée) ;

  • Anticiper l’évolution (multi-auteurs, tags, localisation…).

Les modèles principaux

  • BlogArticle : contient tout le contenu éditorial, les métas, la durée de lecture, le statut, la FAQ et les catégories liées.

  • BlogCategory : pour créer des classements croisés et thématiques.

  • BlogFaq : pour afficher une section de questions/réponses dans l’article.

Chaque élément est lié par Prisma via des relations bien définies, permettant une navigation croisée puissante.

Un éditeur WYSIWYG simple et efficace

Pourquoi TinyMCE ?

  • L’édition se fait directement dans le navigateur avec une interface claire (gras, titres, listes, tableaux…)

  • L’output est du HTML directement interprétable côté frontend (pas de conversion Markdown)

  • Moins de choix = moins d’erreurs : volontairement limité pour éviter les contenus cassés ou mal optimisés

Fonctions spécifiques ajoutées dans mon back-office

  • Champ titre + génération automatique du slug :

const slugify = (title: string) =>
  title
    .toLowerCase()
    .replace(/[^a-z0-9]+/g, "-")
    .replace(/(^-|-$)/g, "");
  • Image de couverture avec aperçu immédiat

  • Rédaction du contenu via TinyMCE

  • Sélection multiple de catégories

  • Définition du statut de publication (draft ou published)

  • Édition du metaTitle et metaDescription avec compteur dynamique + couleurs indicatrices (SEO OK/warning/dépassé)

  • Section FAQ dynamique (ajout/suppression de questions-réponses à la volée)

Une navigation croisée pour maximiser le maillage interne et la rétention

1. Catégories cliquables

Les articles affichent leurs catégories sous forme de chips cliquables.
Cliquer renvoie vers /blog/categories/[slug] qui liste tous les articles de cette catégorie.

Objectif : encourager la navigation thématique, prolonger la session, et améliorer l’indexation verticale (silo SEO).

2. Fil d’Ariane dynamique

Présent en haut de chaque article :
Accueil > Blog > Articles > Nom de l’article

Intégré en JSON-LD :

{
  "@context": "https://schema.org",
  "@type": "BreadcrumbList",
  "itemListElement": [
    { "@type": "ListItem", "position": 1, "name": "Accueil", "item": "https://saas-path.com/" },
    { "@type": "ListItem", "position": 2, "name": "Blog", "item": "https://saas-path.com/blog" },
    { "@type": "ListItem", "position": 3, "name": "Articles", "item": "https://saas-path.com/blog/articles" },
    { "@type": "ListItem", "position": 4, "name": "Titre article", "item": "https://saas-path.com/blog/articles/titre-article" }
  ]
}

Objectif : guider visuellement le lecteur et renforcer la compréhension sémantique côté moteur.

3. Articles similaires (catégories croisées)

Lors de l'affichage d’un article, deux articles sont sélectionnés s’ils :

  • sont publiés (status = published)

  • partagent au moins une catégorie avec l’article courant

  • ne sont pas l’article en cours

  • sont triés par date récente

Objectif : proposer un contenu contextuel pertinent, tout en augmentant la rétention et le nombre de pages vues.

Une page article ultra-optimisée (UX & SEO)

Affichage utilisateur

  • <h1> avec le titre

  • Durée de lecture estimée

  • Liste des catégories cliquables

  • Date de publication et mise à jour

  • Image de couverture (avec alt)

  • Contenu HTML enrichi + auto target="_blank"

  • FAQ dynamique (via <details>, accessible)

  • Articles similaires en fin de page

Injection SEO technique

  • <title> dynamique issu de metaTitle

  • <meta name="description"> issu de metaDescription

  • OpenGraph complet : titre, image, description

  • JSON-LD : BlogPosting, BreadcrumbList, FAQPage

  • Robots : max-image-preview:large

Exemple de JSON-LD pour BlogPosting

{
  "@context": "https://schema.org",
  "@type": "BlogPosting",
  "headline": "Titre de l’article",
  "description": "Résumé SEO",
  "image": "https://...",
  "datePublished": "2025-06-20T00:00:00Z",
  "dateModified": "2025-06-23T00:00:00Z",
  "author": {
    "@type": "Person",
    "name": "Nicolas C",
    "url": "https://x.com/NicolasCDev"
  },
  "articleBody": "..."
}

Pourquoi autant de précision ? Pour maximiser l’apparition dans Discover, les Rich Results (FAQ, breadcrumbs…) et renforcer la présence du site dans les SERP.

Durée de lecture calculée dès la sauvegarde

J’ai choisi de calculer la durée de lecture (readingTimeMinutes) à la création ou mise à jour d’un article, côté backend, avec une petite lib ou formule personnalisée (~200 mots/minute).

→ Exemple simple :

import readingTime from "reading-time";

const stats = readingTime(article.content);
article.readingTimeMinutes = Math.ceil(stats.minutes);

Avantage : le temps de lecture est persisté en DB et affichable en SSR sans recalcul côté client plus rapide, plus stable.

Sitemap XML dynamique pour garantir l’indexation

Le sitemap généré dynamiquement comprend :

  • Pages fixes (/, /blog, /blog/articles, /blog/categories)

  • Articles publiés (avec lastmod = updatedAt)

  • Catégories existantes

→ Objectif : garantir une exploration rapide, une indexation complète, et un sitemap qui évolue sans effort manuel.

Conclusion

En partant de zéro, j’ai construit un CMS complet, léger, SEO-friendly et intégré 100 % à mon SaaS. Pas de plugin à maintenir. Pas de backoffice externe.
Chaque brique est pensée pour accélérer la rédaction, améliorer le SEO, et faciliter la lecture.

Tu peux t’en inspirer aujourd’hui pour créer ton propre système ou builder une solution CMS embarquée pour tes clients SaaS.

👉 D’autres guides pratiques sur SaaS Path

Questions fréquentes

  • Q1 : Est-ce que ça vaut vraiment le coup de créer son propre CMS plutôt qu’utiliser WordPress ou Ghost ?+
    Oui, si tu veux un blog parfaitement intégré à ton stack, sans surcharge. Un CMS maison est souvent plus rapide, plus modulaire, et sans dépendance.
  • Q2 : Peut-on brancher ce CMS sur un back-office existant ?+
    Absolument. Le système fonctionne avec n’importe quel dashboard Next.js ou autre. Il suffit de rajouter l’interface d’édition des articles, catégories, FAQ.
  • Q3 : Comment gérer les auteurs ou permissions ?+
    Ajoute une relation authorId à BlogArticle, puis filtre les actions selon le rôle dans ta base utilisateur. Le système est extensible.
  • Q4 : Ce système est-il compatible avec un site multilingue ?+
    Oui, à condition d’ajouter une table BlogArticleTranslation ou un champ lang. Le routing multilingue peut ensuite suivre la logique /fr/blog/..., /en/blog/..., etc.
  • Q5 : Peut-on utiliser autre chose que TinyMCE ?+
    Oui, TipTap, Lexical ou un éditeur Markdown sont des alternatives. Choisis l’éditeur selon le type de contenu et la liberté que tu veux offrir à l’auteur.

Articles similaires

Plateformes d’avis : G2, Capterra, GetApp : comment booster ton SaaS

Plateformes d’avis : G2, Capterra, GetApp : comment booster ton SaaS

Optimisez votre présence sur G2, Capterra et GetApp pour booster la visibilité de votre SaaS. Straté...

Gérer la TVA européenne avec Stripe Tax

Gérer la TVA européenne avec Stripe Tax

Activez Stripe Tax et automatisez la gestion de la TVA SaaS en Europe. Guide complet + tips comptabl...