Variantes d'images

Chaque thème déclare les variantes d'images (tailles / ratios / formats) qu'il attend. Le pipeline d'upload de l'admin génère chaque variante déclarée à chaque fois qu'un utilisateur upload une image

Chaque thème déclare les variantes d'images (tailles / ratios / formats) qu'il attend. Le pipeline d'upload de l'admin génère chaque variante déclarée à chaque fois qu'un utilisateur upload une image — donc quand votre template appelle pickFormat(view, "small"), le fichier existe déjà à l'URL attendue.

Déclarer les variantes

Dans manifest.ts :

TS
imageFormats: {
  inputFormats: [".jpg", ".jpeg", ".png", ".webp", ".gif"],
  outputFormat: "webp",
  quality: 80,
  variants: [
    { name: "thumbnail", maxWidth: 400, maxHeight: 400, fit: "cover" },
    { name: "small", maxWidth: 600, maxHeight: 600, fit: "contain" },
    { name: "medium", maxWidth: 1200, maxHeight: 1200, fit: "contain" },
    { name: "large", maxWidth: 2000, maxHeight: 2000, fit: "contain" },
  ],
}

Champs

inputFormats

Extensions acceptées en upload. L'admin filtre les uploads qui ne matchent pas.

outputFormat

Format de sortie. webp est recommandé (meilleur ratio compression / qualité, support universel des navigateurs modernes). jpeg et png sont aussi supportés mais déconseillés.

quality

Qualité par défaut (0-100). 80 est un bon compromis. Surcharger par variante via format.quality.

variants

Chaque variante a :

  • name — utilisé comme clé dans media.formats et dans pickFormat(view, name). Convention : thumbnail, small, medium, large, ou des noms spécifiques au thème.

  • maxWidth / maxHeight — bornes en pixels. Le pipeline ne fait jamais d'upscale au-delà de la taille originale.

  • fit — comment redimensionner :

    • cover — crop pour remplir les dimensions (perd des bords)
    • contain — fit dans les dimensions, ratio préservé
    • inside — fit dans, mais ne grossit jamais (équivalent contain + skip si déjà plus petit)
  • quality? — override la qualité globale

Variantes admin-only

En plus des variantes du thème, le pipeline produit toujours trois variantes admin :

  • admin-thumb — 72×72 (avatars, vignettes de listing)
  • admin-preview — 800×800 (panneau de détails)
  • admin-original — 2000×2000 fit contain, qualité 90 (source de re-crop préservée)

admin-original est la source haute fidélité préservée : 2000 px sur le long axe avec ratio préservé. Pas affiché — utilisé pour re-cropper toute future variante que vous ajouteriez au thème.

Pipeline en pratique

Quand un user upload une image :

  1. L'admin lit le fichier dans un <canvas>
  2. Pour chaque variante (thème + admin-only) : redimensionne + encode en WebP
  3. Upload chaque WebP sur Flexweg à media/<year>/<month>/<slug>-<hex>/<variant>.webp
  4. Crée le document media/<id> en base avec une map formats: { thumbnail: {...}, small: {...}, ... }

Chaque variante a son URL, ses dimensions, ses bytes — disponibles via pickFormat(view, name).

Utiliser dans un template

TSX
import { mediaToView, pickFormat } from "@flexweg/cms-runtime";

function PostCard({ post, hero }) {
  if (!hero) return null;
  const view = mediaToView(hero);
  const thumbnail = pickFormat(view, "thumbnail");
  return (
    <article>
      <img src={thumbnail.url} alt={view.alt} width={thumbnail.width} height={thumbnail.height} />
    </article>
  );
}

pickFormat(view, name) retourne la variante demandée, avec fallback vers defaultFormat puis la plus grande disponible. Donc votre template ne crashe jamais sur un média ancien qui n'a pas la variante demandée.

Choisir les bonnes variantes pour votre thème

  • Tile de listing 300px de largethumbnail à 400×400 cover
  • Hero plein largeur sur desktop (1200px)medium à 1200×1200 contain
  • Hero ultra-wide (2000px)large à 2000×2000 contain

Le pipeline ne sait pas générer plus grand que 2000 px sur le long axe à partir de admin-original. Si vous voulez du 4K, déclarez une variante xlarge à 4000×4000 — le pipeline la générera depuis l'upload original (si assez grand) ou retombera sur admin-original sinon.

Quand changer les variantes

Si vous changez imageFormats après que des utilisateurs ont déjà uploadé des médias :

  • Les médias anciens n'ont pas les nouvelles variantes — pickFormat retombe sur la plus grande disponible
  • Les médias futurs auront toutes les nouvelles variantes
  • Pour générer rétroactivement les nouvelles variantes sur l'historique : pas d'UI pour ça aujourd'hui. Il faudrait re-uploader chaque média manuellement, ou écrire un script qui itère via useCmsData().media et appelle processImage.

Le mode SVG

Les SVG sont uploadés tels quels, sans génération de variantes. Le pipeline les passe par DOMPurify côté admin pour neutraliser les scripts. Au runtime, ils peuvent être rendus via <img> ou inlined via dangerouslySetInnerHTML.

Quality vs taille

Quelques benchmarks indicatifs (image 1920×1080 photo) :

  • Qualité 60 → ~50 Ko WebP
  • Qualité 80 → ~100 Ko WebP
  • Qualité 90 → ~250 Ko WebP

Pour des thèmes éditoriaux où la qualité d'image compte, mettez 85-90. Pour des thèmes vitrine / SaaS où le poids prime, 75-80 suffit.