Desarrollo de Bloques Personalizados para Gutenberg con React
El ecosistema de WordPress ha experimentado una transformación radical desde la introducción del editor Gutenberg. Lo que comenzó como una simple alternativa al clásico editor TinyMCE se ha convertido en una plataforma de desarrollo frontend basada en React. Para cualquier desarrollador que quiera dominar WordPress en 2025, el dominio de los bloques Gutenberg personalizados ya no es opcional, es una habilidad fundamental.
Este artículo es una guía técnica exhaustiva para crear bloques desde cero. Vamos a profundizar en el ecosistema de React WordPress, las herramientas modernas de scaffolding y las mejores prácticas para el desarrollo bloques Gutenberg que sean rápidos, mantenibles y escalables. Prepárate para ensuciarte las manos con JavaScript moderno, JSX y la API de bloques.
¿Por qué React es el Corazón de Gutenberg?
Para entender el desarrollo bloques Gutenberg, primero debemos aceptar una realidad: el editor de WordPress ya no es PHP. Es una aplicación de una sola página (SPA) construida con React WordPress.
La Arquitectura del Editor
El editor Gutenberg utiliza React para manejar el estado, el renderizado y la interactividad. Cuando creas un bloque personalizado, estás escribiendo componentes de React que se montan dentro de un iframe o directamente en el DOM del editor.
[INFO] Aunque el editor usa React, no necesitas ser un experto en React para empezar. La abstracción de la API de bloques (registerBlockType) simplifica mucho el proceso. Sin embargo, cuanto más sepas de React, más potentes serán tus bloques.
Ventajas de Usar React en WordPress
- Componentes Reutilizables: Puedes crear componentes UI (botones, sliders, formularios) y reutilizarlos en múltiples bloques.
- Estado Local y Global: Manejas el estado del bloque con hooks como
useStateyuseSelectpara leer datos del store central de WordPress. - Rendimiento: React virtual DOM asegura que solo se actualice lo necesario, manteniendo el editor fluido incluso con bloques complejos.
- Ecosistema npm: Accedes a miles de librerías de React (como react-select, react-dates, etc.) para enriquecer tus bloques.
Preparando el Entorno de Desarrollo para 2025
Antes de escribir código, necesitas un entorno moderno. Olvídate de incluir scripts manualmente. Usaremos las herramientas oficiales de WordPress.
Requisitos
- Node.js (versión 18 o superior)
- npm o yarn
- WordPress 6.5+ (preferiblemente la última versión)
- Un plugin base (puedes usar un plugin boilerplate o un tema hijo)
Scaffolding con @wordpress/create-block
La forma más rápida de empezar con el editor Gutenberg avanzado es usando el paquete oficial de scaffolding.
npx @wordpress/create-block mi-bloque-personalizado
cd mi-bloque-personalizado
npm start
Este comando genera toda la estructura de un bloque moderno: src/, build/, block.json, package.json y los scripts de compilación (webpack configurado con Babel).
[TIP] Si quieres crear un bloque estático (sin interacción backend), usa npx @wordpress/create-block@latest --no-plugin. Esto generará solo los archivos del bloque para incluirlos en un tema.
Estructura de Archivos Esencial
mi-bloque-personalizado/
├── build/ # Archivos compilados (JS y CSS)
├── src/
│ ├── edit.js # Componente de edición (React)
│ ├── save.js # Componente de guardado (HTML estático)
│ ├── index.js # Registro del bloque
│ └── style.scss # Estilos del bloque
├── block.json # Metadatos del bloque
└── package.json
Creando tu Primer Bloque Avanzado: "Testimonial Slider"
Vamos a construir un bloque que no es un simple encabezado. Crearemos un slider de testimonios con navegación por flechas y dots. Esto demostrará el verdadero poder de React WordPress.
1. Configuración del block.json
El block.json es el nuevo estándar. Centraliza todos los metadatos.
{
"apiVersion": 3,
"name": "mi-plugin/testimonial-slider",
"title": "Testimonial Slider",
"category": "widgets",
"icon": "format-quote",
"description": "Un slider de testimonios personalizado con React.",
"supports": {
"html": false,
"align": ["wide", "full"]
},
"attributes": {
"slides": {
"type": "array",
"default": [
{ "text": "Excelente servicio", "author": "Juan Pérez" }
]
},
"autoplay": {
"type": "boolean",
"default": false
}
},
"editorScript": "file:./build/index.js",
"style": "file:./build/style-index.css"
}
Puntos clave:
apiVersion: 3es obligatorio para bloques modernos.- Los
attributesdefinen el estado del bloque. Usamos un array para los slides. supportscontrola características básicas como alineación.
2. El Componente de Edición (edit.js)
Aquí es donde ocurre la magia de React WordPress. Construimos una UI dentro del editor.
import { __ } from '@wordpress/i18n';
import { useBlockProps, InspectorControls } from '@wordpress/block-editor';
import { PanelBody, ToggleControl, Button, TextControl } from '@wordpress/components';
import { useState } from '@wordpress/element';
export default function Edit({ attributes, setAttributes }) {
const { slides, autoplay } = attributes;
const [currentSlide, setCurrentSlide] = useState(0);
const addSlide = () => {
const newSlides = [...slides, { text: '', author: '' }];
setAttributes({ slides: newSlides });
};
const updateSlide = (index, key, value) => {
const newSlides = slides.map((slide, i) => {
if (i === index) {
return { ...slide, [key]: value };
}
return slide;
});
setAttributes({ slides: newSlides });
};
const removeSlide = (index) => {
const newSlides = slides.filter((_, i) => i !== index);
setAttributes({ slides: newSlides });
};
return (
<div { ...useBlockProps() }>
<InspectorControls>
<PanelBody title={ __('Configuración', 'mi-plugin') }>
<ToggleControl
label="Autoplay"
checked={ autoplay }
onChange={ (value) => setAttributes({ autoplay: value }) }
/>
</PanelBody>
</InspectorControls>
<div className="slider-preview">
{ slides.map((slide, index) => (
<div key={ index } className="slide-item">
<TextControl
label="Texto del testimonio"
value={ slide.text }
onChange={ (value) => updateSlide(index, 'text', value) }
/>
<TextControl
label="Autor"
value={ slide.author }
onChange={ (value) => updateSlide(index, 'author', value) }
/>
<Button isDestructive onClick={ () => removeSlide(index) }>
Eliminar
</Button>
</div>
)) }
<Button isPrimary onClick={ addSlide }>
Añadir Testimonio
</Button>
</div>
</div>
);
}
[WARNING] No uses Math.random() para las keys en React. Siempre usa un índice o un ID único. En este caso, el índice es suficiente porque el array es estático durante la edición.
3. El Componente de Guardado (save.js)
Gutenberg separa la edición del renderizado en el frontend. Aquí generamos el HTML estático.
import { useBlockProps } from '@wordpress/block-editor';
export default function save({ attributes }) {
const { slides, autoplay } = attributes;
return (
<div { ...useBlockProps.save() } data-autoplay={ autoplay }>
<div className="swiper-container">
<div className="swiper-wrapper">
{ slides.map((slide, index) => (
<div key={ index } className="swiper-slide">
<blockquote>
<p>{ slide.text }</p>
<footer>{ slide.author }</footer>
</blockquote>
</div>
)) }
</div>
<div className="swiper-pagination"></div>
<div className="swiper-button-prev"></div>
<div className="swiper-button-next"></div>
</div>
</div>
);
}
[INFO] El frontend (save.js) debe ser HTML estático. Si necesitas interactividad en el frontend (como el slider), debes encolar un script de JavaScript aparte (por ejemplo, usando Swiper.js) que se ejecute en el tema.
Buenas Prácticas para el Desarrollo de Bloques Gutenberg
Crear un bloque funcional es solo el primer paso. Para que sea profesional y escalable, sigue estas reglas.
1. Usa useSelect y useDispatch para Datos Globales
Si tu bloque necesita acceder a datos de WordPress (posts, usuarios, categorías), no hagas peticiones AJAX manuales. Usa los hooks de datos de WordPress.
import { useSelect } from '@wordpress/data';
import { store as coreStore } from '@wordpress/core-data';
const posts = useSelect((select) => {
return select(coreStore).getEntityRecords('postType', 'post', {
perPage: 5,
});
}, []);
2. Optimiza el Rendimiento con useMemo y useCallback
Los bloques se re-renderizan constantemente. Usa useMemo para evitar cálculos costosos y useCallback para evitar crear nuevas funciones en cada render.
import { useMemo, useCallback } from '@wordpress/element';
const sortedSlides = useMemo(() => {
return [...slides].sort((a, b) => a.order - b.order);
}, [slides]);
const handleSlideChange = useCallback((index) => {
setCurrentSlide(index);
}, []);
3. Estilos Modulares con CSS-in-JS o SCSS
Usa los archivos style.scss y editor.scss que genera el scaffolding. Separa los estilos del editor de los del frontend.
// style.scss (frontend + editor)
.wp-block-mi-plugin-testimonial-slider {
.swiper-container {
max-width: 800px;
margin: 0 auto;
}
}
// editor.scss (solo editor)
.wp-block-mi-plugin-testimonial-slider {
.slide-item {
border: 1px dashed #ccc;
padding: 20px;
margin-bottom: 10px;
}
}
4. Internacionalización (i18n)
Nunca hardcodees strings. Usa __() y _x() de @wordpress/i18n. Esto permite que tu bloque sea traducido.
import { __ } from '@wordpress/i18n';
<Button>{ __('Añadir Slide', 'mi-plugin') }</Button>
Despliegue y Mantenimiento en WordPress React 2025
Una vez que tu bloque está listo, el despliegue es simple.
Compilación para Producción
npm run build
Esto genera los archivos optimizados en la carpeta build/. Luego, activas tu plugin o tema y el bloque estará disponible en el editor.
Actualización y Versionado
Usa el campo version en block.json. Cada vez que actualices el bloque, cambia la versión para forzar la recarga del script en el navegador del usuario.
{
"version": "2.0.0"
}
[WARNING] Si cambias la estructura de los attributes (por ejemplo, añades un nuevo campo), asegúrate de que el código de save.js sea compatible con versiones anteriores. De lo contrario, los bloques existentes en las entradas podrían romperse.
Conclusión: El Futuro es Reactivo
El desarrollo bloques Gutenberg con React no es una moda pasajera. Es la evolución natural de WordPress hacia una plataforma más moderna y flexible. En 2025, los desarrolladores que dominen la creación de bloques personalizados serán los más demandados.
Hemos cubierto desde el scaffolding con @wordpress/create-block hasta la construcción de un slider funcional, pasando por buenas prácticas de rendimiento y estado. La clave está en entender que ya no estás escribiendo plugins PHP; estás construyendo aplicaciones React que se integran perfectamente en el ecosistema de WordPress.
Ahora es tu turno. Abre tu terminal, ejecuta npx @wordpress/create-block y empieza a experimentar. El editor Gutenberg avanzado te espera.
Recursos adicionales:
