IA & Automation

Génère 50 bannières d'un coup avec Node.js — mais arrête d'écrire ton texte en SVG à la main

Un pipeline Node.js produit cinquante variantes de visuels sociaux en moins d'une minute. Sharp pour composer et optimiser, Satori pour le texte — et tout ce qu'il ne faut surtout pas coder à la main.

7 nov 20259 min de lecturePASCAL POTVIN
Écouter l'article

Le goulot d'étranglement des visuels sociaux

Quand tu gères les réseaux sociaux d'une marque active, la production de visuels devient vite ingérable. Chaque publication demande des variantes pour Instagram, X, LinkedIn et l'image Open Graph — au minimum quatre formats par contenu. Multiplie par cinq publications par semaine, et tu te retrouves à produire vingt visuels hebdomadaires à la main. Ce rythme n'est pas tenable.

L'approche programmatique consiste à définir des templates comme du code, à y injecter du contenu dynamique, et à générer automatiquement toutes les variantes. Un script qui s'exécute en quelques secondes remplace des heures de copier-coller dans Photoshop, et le résultat est parfaitement cohérent d'une variante à l'autre. C'est l'approche que j'utilise pour mes clients : cinquante bannières à partir d'un seul template, en moins d'une minute. Mais il y a un endroit précis où la plupart des tutoriels te font perdre ton temps, et je vais y venir.

Sharp : le moteur de composition et d'optimisation

Sharp encapsule libvips, un moteur de traitement d'image en C++ extrêmement rapide — plusieurs fois plus véloce que les alternatives en pur JavaScript. Il accepte JPEG, PNG, WebP, AVIF, TIFF, GIF et SVG en entrée et en sortie. La version 0.34, sortie au premier trimestre 2026, a apporté des choses qui comptent pour un pipeline de production : l'encodage AVIF de première classe via libavif, le décodage HEIC natif sans clé de licence séparée, un build WASM durci pour réduire les démarrages à froid en serverless, et un pool de workers en process. Concrètement, ça rend le déploiement en fonction serverless bien plus propre qu'il y a un an.

L'API est une chaîne de transformations : on charge une source, on redimensionne, on compose des calques, on exporte.

js
import sharp from "sharp";

await sharp("background.jpg")
  .resize(1200, 630)
  .composite([
    { input: logoBuffer, gravity: "northwest" },
    { input: textSvgBuffer, gravity: "center" },
  ])
  .toFormat("webp", { quality: 80 })
  .toFile("output.webp");

Sa limite, c'est qu'il n'a aucun rendu de texte natif. Pour ajouter du texte, il faut lui passer un overlay SVG qu'il rastérise — et c'est exactement là que beaucoup s'enlisent.

Pour le texte, n'écris pas du SVG à la main : Satori

Construire un fragment SVG text à la main, en calculant les positions, les retours à la ligne et l'ajustement de la police, est pénible et fragile. Dès que le texte est dynamique — un titre d'article de longueur variable — ça casse. La bonne réponse en 2026, c'est Satori, la bibliothèque de Vercel (version 0.18) qui convertit du HTML et du CSS en SVG sans navigateur headless, en supportant flexbox et un sous-ensemble large de CSS. C'est le moteur derrière @vercel/og (version 0.11), qui alimente des milliers de cartes sociales Next.js.

jsx
// Satori : tu écris du JSX/CSS, pas des <text> SVG à la main
const svg = await satori(
  <div style={{ display: "flex", flexDirection: "column", padding: 64,
                background: "#0b1020", color: "white", width: 1200, height: 630 }}>
    <h1 style={{ fontSize: 64, fontWeight: 700 }}>{title}</h1>
    <p style={{ fontSize: 28, opacity: 0.8 }}>{excerpt}</p>
  </div>,
  { width: 1200, height: 630, fonts: [/* … */] }
);

Ma règle est devenue simple : Satori produit le SVG du texte avec une vraie mise en page, et Sharp s'occupe de ce qu'il fait le mieux — composer ce SVG sur un fond, rastériser, optimiser et exporter. Chacun à sa place.

Séparer le template du contenu

La clé d'un système maintenable, c'est de ne jamais mélanger la définition du template et le contenu. Je définis chaque template comme un objet de configuration : dimensions, calques, positions, styles, zones de texte dynamiques. Le moteur de rendu lit cette config, charge les assets, injecte les données et produit l'image. Ajouter un format se fait en ajoutant un objet de configuration, sans toucher au code de rendu. Astuce qui m'a sauvé sur le multi-format : je positionne les éléments en pourcentage relatif plutôt qu'en pixels absolus, ce qui permet de passer d'un ratio à l'autre sans tout recalculer.

Pour le choix du moteur selon le besoin, voici comment je tranche.

OutilRôleQuand l'utiliser
Sharpcomposition, rastérisation, optimisationsocle de tout pipeline
Satori / @vercel/ogHTML/CSS → SVGtout visuel à texte dynamique
node-canvas (Cairo)API Canvas 2D serveurrendu de texte sans SVG
Puppeteer / Playwrightscreenshot d'une page HTMLcompositions très complexes, plein CSS
Bannerbear, Cloudinary, PlacidSaaS + API RESTéquipes sans envie de maintenir du code

Un mot sur Jimp, souvent cité comme alternative en pur JavaScript : il a été réécrit en TypeScript et est passé en version 1.x. Il reste pratique pour éviter les dépendances natives, mais ses performances restent nettement en dessous de Sharp — je ne l'utilise que sur des contraintes de déploiement particulières.

Le pipeline de production

En production, j'intègre la génération dans un workflow plus large. Un webhook se déclenche à la publication d'un article dans le CMS ; le script Node.js récupère le titre, l'extrait et l'image à la une, génère les visuels pour toutes les plateformes, les optimise et les dépose dans un bucket S3 derrière un CDN. Le gestionnaire de réseaux sociaux n'a plus qu'à planifier la publication, visuels déjà prêts.

L'optimisation du poids est critique : je vise un maximum de 300 Ko par visuel pour un chargement rapide en mobile. WebP offre un excellent compromis qualité-poids, et avec l'AVIF désormais de première classe dans Sharp 0.34, je l'utilise quand la plateforme cible le supporte. Le gain mesuré sur mes projets est net : deux à trois heures de travail graphique hebdomadaire remplacées par moins d'une minute d'exécution. Mais le vrai bénéfice n'est pas le temps — c'est la cohérence. Chaque visuel respecte exactement les mêmes marges, polices et règles de composition, sans la variabilité inhérente au travail manuel répété. Et en confiant le texte à Satori plutôt qu'à des <text> SVG bricolés, le système ne casse plus dès qu'un titre dépasse la longueur prévue.

§ COMMENTAIRES

Laisser un commentaire