Guide de développement de blocs

Créez des blocs personnalisés pour votre site Cmssy headless - defineBlock, fields, le composant de bloc et le context.

29 juin 2026

Anatomie d'un bloc

Un bloc Cmssy vit dans votre propre repo Next.js sous forme de dossier dans blocks/ :

  • block.ts — déclare le bloc avec defineBlock + fields (son type, son label et son schéma éditable)
  • Hero.tsx — le composant React qui rend le contenu

Enregistrez le bloc dans cmssy/blocks.ts. L'éditeur lit le schéma de chaque bloc via le pont SDK : ajouter un bloc à une page génère un formulaire d'édition à partir de vos fields.


Définir un bloc

// blocks/hero/block.ts
import { defineBlock, fields } from "@cmssy/react";
import Hero from "./Hero";

// Exporté séparément, pour que le composant en dérive ses props.
export const heroProps = {
  heading: fields.text({ label: "Heading", defaultValue: "Welcome" }),
  body: fields.richText({ label: "Body" }),
  ctaUrl: fields.link({ label: "CTA URL", defaultValue: "/signup" }),
  showCta: fields.boolean({ label: "Show CTA", defaultValue: true }),
};

export const heroBlock = defineBlock({
  type: "hero",
  label: "Hero",
  component: Hero,
  props: heroProps,
});

Types de champs : text, textarea, richText, markdown, number, date, datetime, boolean, color, media, link, url, email, select, radio, multiselect, relation, repeater, table, json, form, pageSelector. Voir Schéma & types de champs.


Le composant de bloc

Les blocs reçoivent { content, context, data }. Le contenu est déjà résolu pour la locale active, lisez donc les champs directement.

// blocks/hero/Hero.tsx
import type { BlockProps } from "@cmssy/react";
import { heroProps } from "./block";

export default function Hero({ content, context }: BlockProps<typeof heroProps>) {
  // Typé depuis le schéma : heading est une string, showCta un boolean.
  const { heading, showCta, ctaUrl } = content;
  const isPreview = context?.isPreview ?? false;

  return (
    <section>
      <h1>{heading}</h1>
      {showCta && <a href={ctaUrl}>Get started</a>}
    </section>
  );
}

BlockProps<typeof heroProps> fait du schéma le seul endroit où un champ est nommé. Renommez heading et le composant cesse de compiler - au lieu de n'afficher plus rien en silence, ce qu'aurait fait la lecture de content.heading sur un Record<string, unknown>. Si le bloc a un loader, passez son type de retour en second argument : BlockProps<typeof heroProps, Posts> type aussi la prop data.

context transporte locale ({ current, default, enabled }) et isPreview (true dans l'éditeur), plus forms pour tout formulaire référencé par le bloc. auth et workspace sont présents quand votre application les fournit via buildBlockContext. Une UI sensible à la locale lit context.locale.enabled. Pour vos propres modèles ou enregistrements, utilisez createCmssyClient ; pour charger pendant le SSR, ajoutez un loader et lisez son résultat dans data. Voir Fonctionnalités avancées et Loaders serveur.


Enregistrer & livrer

// cmssy/blocks.ts
import { heroBlock } from "@/blocks/hero/block";
export const blocks = [heroBlock];

Lancez pnpm dev, ouvrez l'éditeur de page, et votre bloc apparaît dans le sélecteur. Déployez votre app Next.js pour livrer — il n'y a pas d'étape séparée de build ou de publication de bloc.


Prochaines étapes

Commencez à créer des blocs

Configurez le SDK, puis créez et enregistrez votre premier bloc.