Actualizado el 26/04/2026: Ampliamos la guía con el flujo completo para crear tu primer bloque personalizado con React, la configuración de theme.json v3, y las mejores prácticas de testing y rendimiento para proyectos FSE en 2026.

Gutenberg Full Site Editing (FSE) transformó la forma en que construís y mantenés tu sitio WordPress. En lugar de manejar código, CSS o templates heredados, ahora contás con una interfaz visual completa donde diseñás todo: desde la página de inicio hasta los resultados de búsqueda. Es el editor de bloques expandido a toda la estructura del sitio.
En 30 segundos
- Gutenberg FSE es el editor de bloques expandido a templates, patrones y estilos globales del sitio completo.
- Con WordPress 6.8, FSE ya no es experimental: es el estándar para desarrollar temas en 2026.
- theme.json centraliza colores, tipografías y espaciados, reemplazando el CSS disperso en múltiples archivos.
- Los bloques personalizados se registran con
block.json, sin necesidad de hooks complejos en functions.php. - La paleta de comandos (
Ctrl+K) acelera el flujo de trabajo en el editor de sitio. - Twenty Twenty-Five incluye 70+ patrones listos para usar como punto de partida.
Gutenberg es el editor de bloques visual de WordPress, desarrollado por WordPress.com y la comunidad, que permite diseñar contenido y sitios completos usando bloques reutilizables en lugar de código HTML.
¿Qué es Full Site Editing (FSE) y por qué lo necesitás en 2026?
Full Site Editing es la diferencia entre tener un tema y tener un sistema de diseño. Los temas clásicos funcionan con archivos PHP: header.php, single.php, archive.php. Cada cambio visual requiere editar código o usar un page builder que agrega capas de complejidad. FSE reemplaza todo eso con bloques que editás visualmente, directamente en el editor.
La diferencia práctica es grande. Con un tema clásico, cambiar la estructura del header implica abrir el archivo PHP, identificar dónde está el markup, modificarlo sin romper nada. Con FSE, abrís el Site Editor, navegás a la parte de plantilla «Header», y la modificás como si fuera cualquier otro contenido. Sin código, sin archivos, sin riesgo de dejar el sitio caído.
WordPress 6.8 consolida FSE como el estándar definitivo. Los temas que siguen usando el sistema clásico de PHP no van a desaparecer de un día para el otro, pero tampoco van a recibir las mejoras de rendimiento ni las nuevas APIs. El argumento técnico más concreto: los temas de bloques generan HTML limpio y semántico, sin el peso de scripts adicionales ni estilos cargados innecesariamente. Eso se traduce en scores de PageSpeed entre 95 y 100 en sitios bien configurados.
Diferencias clave: bloques, plantillas, bloques reutilizables y partes de plantilla
Acá hay un punto de confusión frecuente, sobre todo para quienes vienen de sistemas clásicos. Gutenberg maneja cuatro conceptos distintos que parecen similares pero tienen comportamientos muy diferentes. Entender la diferencia ahorra horas de debugging.
Los bloques individuales son la unidad base: un párrafo, una imagen, un botón. Existen dentro de una página o entrada, y no tienen existencia propia fuera de ese contexto. Si los modificás en una página, solo cambia en esa página.
Los bloques reutilizables (ahora llamados «patrones sincronizados» desde WordPress 6.3) son bloques guardados que podés insertar en múltiples lugares. Lo importante: cualquier cambio que hagas en uno se replica en todas las instancias. Son útiles para elementos de contenido que se repiten, como un bloque de CTA o un aviso legal. Ojo: no son estructurales. No controlan el layout del sitio. Lo explicamos a fondo en comunidad de WordPress y sus recursos.
Las partes de plantilla son otro nivel. Son fragmentos reutilizables de la estructura del sitio: el header, el footer, una sidebar. Viven en la carpeta parts/ del tema como archivos HTML. Se sincronizan, igual que los patrones sincronizados, pero su propósito es estructural. Si modificás el header desde el Site Editor, ese cambio afecta todas las páginas que usan esa parte. Las plantillas completas (templates/) combinan partes de plantilla y bloques para armar cada tipo de página.
En la práctica: usá patrones sincronizados para contenido repetido dentro de páginas. Usá partes de plantilla para elementos de estructura del sitio. Y usá plantillas para definir el layout de cada tipo de contenido (single, archive, 404). Mezclar estos conceptos es el error más común al empezar con FSE.
Requisitos técnicos y herramientas para crear un tema Gutenberg
Para trabajar con Full Site Editing necesitás WordPress 6.7 como mínimo, aunque lo recomendable es usar 6.8 para acceder a las APIs más recientes. El plugin Gutenberg es opcional: WordPress ya incluye el editor integrado, pero instalarlo te da acceso a features en desarrollo antes de que lleguen al core.
Del lado del desarrollo, el stack básico es Node.js LTS y npm. Nada más. VS Code funciona bien con las extensiones de PHP y JavaScript. Para crear tu primer bloque personalizado, la herramienta recomendada es @wordpress/create-block, que genera toda la estructura con un solo comando:
npx @wordpress/create-block@latest mi-bloqueEso te da un bloque funcional con block.json, edit.js, save.js y la configuración de wp-scripts lista para usar. No necesitás configurar Webpack, Babel ni nada de eso manualmente. wp-scripts maneja el build por vos.
Si querés desarrollar sin código, existen plugins como Genesis Custom Blocks o Lazy Blocks que permiten crear bloques desde una interfaz visual. Son válidos para casos simples. El tema es que tienen limitaciones cuando necesitás lógica más compleja o integración con APIs externas. Para proyectos serios, la ruta con React te da control total.
Un detalle que ahorra tiempo: agregá define( 'WP_DEVELOPMENT_MODE', 'theme' ); en tu wp-config.php. Eso deshabilita el caché del theme.json durante el desarrollo. Sin esa línea, cada cambio en el archivo requiere limpiar caché manualmente para ver los resultados. El Site Editor está disponible directamente en wp-admin/site-editor.php. Relacionado: recursos y soporte de la comunidad WordPress.
Estructura de un tema de bloques vs tema tradicional
La diferencia estructural entre un tema clásico y uno de bloques es más profunda que el cambio de extensión de archivo. No es solo reemplazar .php por .html. Es un modelo distinto de cómo el tema comunica su lógica a WordPress.
| Tema clásico (PHP) | Tema de bloques (FSE) |
|---|---|
header.php, footer.php | parts/header.html, parts/footer.html |
single.php, archive.php | templates/single.html, templates/archive.html |
functions.php con hooks | theme.json + block.json |
style.css global | CSS por bloque + estilos en theme.json |
| Customizer API | Global Styles en Site Editor |
| Template hierarchy de PHP | Jerarquía de templates HTML |


La carpeta templates/ contiene los archivos HTML para cada tipo de página: index.html (obligatorio), single.html, archive.html, 404.html, y los que necesites. La carpeta parts/ guarda las partes reutilizables. Cada archivo es HTML puro con comentarios de bloque de Gutenberg adentro.
Lo que no hay en un tema de bloques bien armado: un functions.php con cien líneas de add_action() y add_filter(). Eso no significa que no puedas tener functions.php, sino que la configuración del diseño ya no vive ahí. Los bloques personalizados tienen su propio block.json, y los estilos globales viven en theme.json. functions.php queda para lógica de negocio real, no para registrar tipografías o definir colores. Relacionado: mejorar la experiencia en WooCommerce.
Estructura y configuración del archivo theme.json
theme.json es el archivo que centraliza todo el sistema de diseño de tu tema. Va en la raíz del tema, al mismo nivel que style.css. Define colores, tipografías, espaciados, y también controla qué opciones ve el usuario en el editor. Actualmente estamos en la versión 3, que trajo soporte para estilos de shadow, mejoras en las propiedades de tipografía y un sistema de spacing más granular.
La estructura básica tiene dos secciones principales: settings (qué capacidades habilitás) y styles (qué valores aplicás por defecto). Un ejemplo mínimo funcional:
{
"$schema": "https://schemas.wp.org/trunk/theme.json",
"version": 3,
"settings": {
"color": {
"palette": [
{ "slug": "primario", "color": "#1a1a2e", "name": "Primario" },
{ "slug": "acento", "color": "#e94560", "name": "Acento" },
{ "slug": "fondo", "color": "#f5f5f5", "name": "Fondo" }
]
},
"typography": {
"fontFamilies": [
{
"fontFamily": "Inter, sans-serif",
"slug": "inter",
"name": "Inter"
}
],
"fontSizes": [
{ "slug": "small", "size": "0.875rem", "name": "Pequeño" },
{ "slug": "medium", "size": "1rem", "name": "Mediano" },
{ "slug": "large", "size": "1.5rem", "name": "Grande" }
]
},
"spacing": {
"spacingScale": {
"operator": "*",
"increment": 1.5,
"steps": 7,
"mediumStep": 1.5,
"unit": "rem"
}
}
},
"styles": {
"color": {
"background": "var(--wp--preset--color--fondo)",
"text": "var(--wp--preset--color--primario)"
},
"typography": {
"fontFamily": "var(--wp--preset--font-family--inter)",
"fontSize": "var(--wp--preset--font-size--medium)"
}
}
}Lo que hace este archivo es generar variables CSS automáticamente. Cada color de la paleta se convierte en --wp--preset--color--primario, y así con tipografías y espaciados. Esas variables las usás tanto en theme.json como en el CSS de tus bloques. El resultado: un sistema coherente donde cambiar un color en un lugar lo actualiza en todo el tema.
También podés definir estilos específicos por bloque. Dentro de styles, la clave blocks te permite apuntar a cualquier bloque de WordPress:
"styles": {
"blocks": {
"core/heading": {
"typography": {
"fontWeight": "700",
"lineHeight": "1.2"
}
},
"core/paragraph": {
"typography": {
"lineHeight": "1.7"
}
}
}
}Ahora bien, hay una limitación que conviene tener clara: theme.json maneja estilos globales y por tipo de bloque, pero no por instancia individual. Si necesitás estilos muy específicos para un bloque particular en una sola página, eso sigue siendo territorio de CSS adicional con clases personalizadas. Para documentación completa de todas las propiedades disponibles, la referencia oficial de Global Settings and Styles es el punto de partida.
Crear tema Gutenberg: tu primer bloque personalizado con React paso a paso
Después de ejecutar npx @wordpress/create-block@latest mi-testimonio, tenés una estructura que incluye los tres archivos clave: block.json (metadata), edit.js (lo que ve el editor) y save.js (lo que se guarda en la base de datos). Entender la diferencia entre edit y save es fundamental: edit puede tener estado dinámico, save debe ser determinístico.
El block.json define los atributos que el bloque va a manejar:
{
"apiVersion": 3,
"name": "mi-tema/testimonio",
"title": "Testimonio",
"description": "Bloque para mostrar testimonios de clientes",
"category": "text",
"icon": "format-quote",
"supports": {
"html": false,
"color": { "background": true, "text": true },
"spacing": { "padding": true }
},
"attributes": {
"texto": { "type": "string", "default": "" },
"autor": { "type": "string", "default": "" },
"cargo": { "type": "string", "default": "" }
},
"editorScript": "file:./index.js",
"style": "file:./style-index.css"
}En edit.js, usás los componentes de Gutenberg para armar la interfaz del editor. El componente RichText es el más común para campos de texto editables:
import { useBlockProps, RichText } from '@wordpress/block-editor';
export default function Edit({ attributes, setAttributes }) {
const { texto, autor, cargo } = attributes;
const blockProps = useBlockProps({ className: 'bloque-testimonio' });
return (
<div { ...blockProps }>
<RichText
tagName="blockquote"
value={ texto }
onChange={ (val) => setAttributes({ texto: val }) }
placeholder="Escribí el testimonio..."
/>
<RichText
tagName="cite"
value={ autor }
onChange={ (val) => setAttributes({ autor: val }) }
placeholder="Nombre del autor"
/>
</div>
);
}El save.js debe devolver el mismo markup pero de forma estática. El error más frecuente al empezar: usar en save algo que cambia dinámicamente (como fechas o datos del usuario). Si edit y save no producen el mismo HTML, WordPress muestra el error de «contenido inválido» y te ofrece intentar recuperar el bloque. Para evitar ese problema, keep it simple en save: solo atributos guardados, sin lógica condicional.
import { useBlockProps, RichText } from '@wordpress/block-editor';
export default function save({ attributes }) {
const { texto, autor, cargo } = attributes;
const blockProps = useBlockProps.save({ className: 'bloque-testimonio' });
return (
<div { ...blockProps }>
<RichText.Content tagName="blockquote" value={ texto } />
<RichText.Content tagName="cite" value={ autor } />
</div>
);
}Para compilar y ver los cambios en tiempo real, usás npm run start desde la carpeta del bloque. Eso activa el watch mode de wp-scripts. Cuando estés listo para producción, npm run build genera los archivos minificados. El bloque se registra en PHP con una sola línea: register_block_type( __DIR__ . '/build' );, que lee automáticamente el block.json compilado. Más detalles del proceso en la guía práctica de creación de bloques con wp-scripts.
Configuración avanzada: colores, tipografía y estilos globales
Una vez que tenés el sistema base de theme.json funcionando, hay configuraciones que marcan la diferencia en proyectos más grandes. Los gradientes, por ejemplo, se definen igual que los colores sólidos pero con la clave gradients: En crear landing pages con bloques Gutenberg profundizamos sobre esto.
"settings": {
"color": {
"gradients": [
{
"slug": "principal",
"gradient": "linear-gradient(135deg, #1a1a2e 0%, #e94560 100%)",
"name": "Gradiente principal"
}
],
"duotone": [
{
"slug": "azul-rojo",
"colors": ["#1a1a2e", "#e94560"],
"name": "Azul y rojo"
}
]
}
}Para tipografías variables (las que usan el formato .woff2 con ejes de variación), theme.json v3 soporta la propiedad fontFace. Eso te permite incluir una fuente variable que ajusta peso y ancho con un solo archivo, en lugar de cargar múltiples variantes. Menos requests HTTP, mejor rendimiento.
Lo que sí conviene controlar desde theme.json es qué opciones le mostrás al usuario en el editor. Si tu diseño usa una paleta fija, probablemente no querés que el usuario pueda elegir colores custom. Podés deshabilitar eso:
"settings": {
"color": {
"custom": false,
"customDuotone": false,
"customGradient": false
},
"typography": {
"customFontSize": false,
"dropCap": false
}
}Eso no es una restricción arbitraria: es diseño de sistema. Si un cliente puede cambiar los colores a su gusto, vas a terminar con un sitio inconsistente en tres meses. Definir los límites desde el tema es parte del trabajo. La sincronización con el editor visual es automática: los cambios en Global Styles (Apariencia → Editor → Estilos) se escriben en la base de datos como sobreescrituras, y tienen prioridad sobre los valores de theme.json.
Testing, debugging y validación de bloques personalizados
El flujo de debugging en bloques Gutenberg tiene sus particularidades. El primer lugar donde mirar siempre es la consola del navegador. Los errores de JavaScript de React aparecen ahí con stack traces bastante claros. Si el bloque no se registra, buscá errores del tipo «Block type not found» o problemas de sintaxis en block.json.
El error más frustrante es el de «Este bloque contiene contenido inesperado o no válido». Aparece cuando el save.js actual genera HTML diferente al que estaba guardado en la base de datos. Pasá a la vista de código (tres puntos en la barra del bloque → Editar como HTML) para ver exactamente qué está guardado. Después comparalo con lo que devuelve tu save.js actual. La diferencia va a estar ahí.
Para evitar ese problema en actualizaciones de bloques, Gutenberg tiene la API de deprecations. Podés registrar versiones anteriores del bloque con su save function original, y WordPress las usa como fallback para migrar contenido viejo. Es trabajo extra, pero es la forma correcta de manejar cambios en bloques que ya tienen contenido en producción.
Para validar el block.json antes de hacer deploy, podés usar el validador online del repositorio oficial o instalar la extensión de VS Code para WordPress que resalta errores de esquema en tiempo real. Los errores más comunes son atributos con tipos mal declarados o scripts referenciando rutas que no existen en el build. Habría que tener más cuidado en ese punto: es el tipo de error que solo aparece en producción si no lo chequeás antes.
Los conflictos con plugins legacy son otro punto de dolor. Plugins que encolan scripts globales en el editor pueden interferir con los componentes de React de Gutenberg. Si un bloque funciona en un sitio limpio pero falla con plugins activados, el método de bisección es el más rápido: desactivá todos los plugins, verificá que funcione, y reactivá de a uno hasta encontrar el conflicto. Cubrimos ese tema en detalle en probar tus cambios en staging antes de publicar.
Mejores prácticas y rendimiento para proyectos FSE en 2026
El principio más importante en desarrollo de bloques: un bloque, una responsabilidad. Un bloque de testimonio hace una sola cosa. No le agregues lógica de carrusel, efectos de animación y un formulario de contacto. Eso es para un plugin, no para un bloque. Los bloques simples son más fáciles de mantener, de debuggear y de actualizar cuando cambian las APIs de WordPress.
Para rendimiento, el punto más directo es la carga de assets. Por defecto, WordPress carga los estilos de todos los bloques registrados en cada página, aunque ese bloque no aparezca ahí. Desde WordPress 5.9, podés activar la carga condicional con "style": "file:./style-index.css" en block.json y asegurarte de que el bloque solo cargue su CSS cuando está presente en la página. Para el JS del editor (editorScript), ese ya solo se carga en el admin.
Accesibilidad: Gutenberg ya maneja mucho por vos si usás sus componentes correctamente. RichText con el tagName adecuado, atributos ARIA donde correspondan, y foco de teclado funcional en el editor. El problema aparece cuando creás markup personalizado sin considerar el contraste de colores o la navegación por teclado. Los estándares WCAG 2.2 aplican igual para bloques que para cualquier otro componente web.
Un punto que se ignora frecuentemente: documentá los atributos de tus bloques. No en comentarios inline del código, sino en el propio block.json con el campo description por atributo si es necesario, y en un README del bloque. Seis meses después vas a agradecer haber escrito qué hace el atributo variante y cuáles son sus valores posibles. Lo mismo aplica para el equipo si hay más personas trabajando en el proyecto.
Finalmente, pensá en la compatibilidad hacia adelante. Las APIs de Gutenberg cambian. El apiVersion en block.json existe exactamente para esto: versión 3 es el estándar actual con WordPress 6.8. Si aparece una versión 4, WordPress va a seguir soportando los bloques v3 por un tiempo largo, pero conviene mantenerse al día. El repositorio de Gutenberg en GitHub tiene el changelog detallado de cada release.
Preguntas frecuentes
¿Cómo crear un bloque personalizado de Gutenberg?
El camino más directo es usar npx @wordpress/create-block@latest nombre-del-bloque. Eso genera la estructura completa con block.json, edit.js y save.js. Después registrás el bloque en PHP con register_block_type( __DIR__ . '/build' ), lo activás como plugin o lo incluís dentro de tu tema, y ya aparece en el insertor de bloques del editor.
¿Qué es Full Site Editing y cómo activarlo?
FSE es el sistema de WordPress que permite editar templates, partes de plantilla y estilos globales del sitio completo desde el editor de bloques. Se activa automáticamente cuando instalás un tema de bloques compatible (como Twenty Twenty-Five). Con un tema clásico activo, la opción no aparece en el menú. Podés acceder directamente desde Apariencia → Editor, o navegando a wp-admin/site-editor.php.
¿Cómo configurar theme.json en un tema Gutenberg?
theme.json va en la raíz del tema, con la clave "version": 3 para usar la versión actual. Dentro de settings definís las opciones disponibles (paleta de colores, familias tipográficas, tamaños de fuente). Dentro de styles aplicás los valores por defecto. Durante el desarrollo, agregá define( 'WP_DEVELOPMENT_MODE', 'theme' ); en wp-config.php para evitar el caché del archivo.
¿Cuál es la diferencia entre bloques reutilizables y partes de plantilla?
Los bloques reutilizables (patrones sincronizados) son piezas de contenido que podés insertar en múltiples páginas y que se sincronizan al editarlos. Las partes de plantilla son elementos estructurales del sitio (header, footer) que viven en parts/ del tema y definen el layout, no el contenido. Usá patrones sincronizados para contenido que se repite en páginas. Usá partes de plantilla para la estructura del sitio.
¿Qué requisitos necesito para desarrollar bloques Gutenberg?
Node.js LTS y npm son los únicos requisitos de sistema. Del lado del conocimiento, necesitás JavaScript y lo básico de React (componentes, props, estado). PHP es necesario solo para el registro del bloque, que es una línea. CSS para los estilos del bloque. No necesitás configurar Webpack ni Babel: wp-scripts maneja el build. Si es tu primer bloque, arrancá con @wordpress/create-block y leé el código generado antes de modificar nada.
Conclusión
FSE con bloques Gutenberg personalizados dejó de ser una apuesta a futuro. Con WordPress 6.8 como base, theme.json v3 estabilizado y las herramientas de wp-scripts maduras, el stack para crear un tema Gutenberg completo es predecible y bien documentado.
Lo que cambió respecto a hace dos años: la fricción inicial bajó bastante. Generar un bloque funcional lleva minutos, no horas. El sistema de deprecations existe para manejar actualizaciones sin romper contenido existente. Y theme.json reemplazó definitivamente el CSS disperso en múltiples archivos con un sistema de diseño centralizado.
El camino más directo para empezar hoy: instalá Twenty Twenty-Five, activá el modo de desarrollo en wp-config.php, y creá tu primer bloque con @wordpress/create-block. No intentes entender todo el sistema de una vez. Un bloque simple funcionando enseña más que leer documentación durante tres días. De ahí en adelante, cada bloque nuevo es más fácil que el anterior.
Si necesitás hosting optimizado para proyectos WordPress con FSE, Donweb ofrece planes con PHP actualizado y entornos de staging para desarrollar sin tocar producción.


