Guía de desarrollo de bloques

Crea bloques personalizados para tu sitio headless de Cmssy - defineBlock, fields, el componente del bloque y el context.

29 de junio de 2026

Anatomía de un bloque

Un bloque de Cmssy vive en tu propio repo de Next.js como una carpeta dentro de blocks/:

  • block.ts — declara el bloque con defineBlock + fields (su tipo, etiqueta y esquema editable)
  • Hero.tsx — el componente React que renderiza el contenido

Registra el bloque en cmssy/blocks.ts. El editor lee el esquema de cada bloque a través del puente del SDK, así que al añadir un bloque a una página se renderiza un formulario de edición a partir de tus fields.


Definir un bloque

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

// Exportado aparte, para que el componente derive de él sus 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,
});

Tipos de campo: text, textarea, richText, markdown, number, date, datetime, boolean, color, media, link, url, email, select, radio, multiselect, relation, repeater, table, json, form, pageSelector. Consulta Esquema y tipos de campo.


El componente del bloque

Los bloques reciben { content, context, data }. El contenido ya está resuelto para el idioma activo, así que lee los campos directamente.

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

export default function Hero({ content, context }: BlockProps<typeof heroProps>) {
  // Tipado desde el esquema: heading es string, showCta es 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> hace del esquema el único sitio donde se nombra un campo. Renombra heading y el componente deja de compilar, en vez de renderizar nada en silencio, que es lo que habría hecho leer content.heading de un Record<string, unknown>. Si el bloque tiene loader, pasa su tipo de retorno como segundo argumento: BlockProps<typeof heroProps, Posts> tipa también la prop data.

context lleva locale ({ current, default, enabled }) e isPreview (true dentro del editor), además de forms para cualquier formulario que el bloque referencie. auth y workspace aparecen cuando tu app los aporta mediante buildBlockContext. La UI sensible al idioma lee context.locale.enabled. Para tus propios modelos o registros usa createCmssyClient; para cargar durante el SSR añade un loader y lee su resultado desde data. Consulta Funciones avanzadas y Loaders de servidor.


Registrar y publicar

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

Ejecuta pnpm dev, abre el editor de páginas y tu bloque aparecerá en el selector. Despliega tu app de Next.js para publicar — no hay un paso separado de build o publicación de bloques.


Próximos pasos

Empieza a crear bloques

Configura el SDK y luego crea y registra tu primer bloque.