Il cliente ti chiede un layout che il block editor standard non regge. Sei bloccato. O imbottisci di HTML dentro un blocco «Custom HTML» — che poi si rompe al primo aggiornamento — o costruisci un blocco Gutenberg su misura. Noi abbiamo scelto la seconda strada, e non solo perché fa più figo. Perché un blocco custom fatto con React è l'unico modo per dare al tuo WordPress la libertà di design che serve a vendere, senza sacrificare performance e manutenibilità.
Perché sviluppare blocchi Gutenberg custom con React fa risparmiare tempo e soldi?
Ogni volta che usi un page builder o un blocco di terze parti, paghi un canone o accumuli debt tecnico. I blocchi custom, invece, li possiedi. Noi, di Meteora Web, partiamo dal conto economico del cliente: un blocco su misura costa una volta, poi rende per anni. Con React dentro Gutenberg ottieni componenti riutilizzabili, stato locale gestito con leve pronte (useState, useEffect) e un pannello di controllo che sembra un'app, non un form anni 2000.
Un esempio concreto: un cliente e-commerce aveva bisogno di un blocco per mostrare i prodotti in saldo con countdown. Con ACF e jQuery il risultato era lento e impossibile da tradurre. Abbiamo costruito un blocco Gutenberg custom in React: attributi per data scadenza, stile del countdown, numero di prodotti. Tempo di sviluppo: due giorni. Manutenzione: zero. Il sito ha caricato il 40% più veloce.
Sponsored Protocol
Differenza tra blocchi statici e dinamici
Un blocco statico salva l'HTML nel post_content. Veloce, ma poco flessibile. Un blocco dinamico (senza save, solo render_callback) genera l'output lato server. Noi usiamo i dinamici per tutto ciò che deve aggiornarsi senza re-salvare il post — es. ultimi articoli, prezzi in tempo reale. Per il blocco custom, invece, il save con JSX ti dà controllo totale sull'output e funziona con il recupero visivo.
Come strutturare un blocco Gutenberg custom con React passo per passo?
Partiamo dalla cartella. Dentro il tema (o plugin) crei blocks/nome-blocco/. Dentro ci metti: block.json (la dichiarazione ufficiale di WordPress — obbligatoria da WP 6.0), edit.js (componente React per l'editor), save.js (output frontend), style.scss, index.js (punto di ingresso).
// block.json
{
"apiVersion": 3,
"name": "meteora/testimonial",
"title": "Testimonial",
"category": "widgets",
"icon": "format-quote",
"attributes": {
"quote": { "type": "string" },
"author": { "type": "string" },
"avatarURL": { "type": "string", "default": "" }
},
"supports": {
"align": ["wide", "full"],
"color": { "background": true, "text": true },
"spacing": { "padding": true }
},
"editorScript": "file:./index.js",
"style": "file:./style-index.css",
"render": "file:./render.php"
}
Nota sul render.php: se il blocco è dinamico, qui scrivi il markup PHP. Noi lo usiamo quando i dati vengono dal database o da API esterne. Per blocchi puramente statici, lascia il save.js e ometti il render.
Sponsored Protocol
Registrare il blocco nel tema
Il modo più pulito: register_block_type( __DIR__ . '/blocks/testimonial' ); in functions.php. WordPress carica automaticamente il block.json e gli script React. Niente enqueue a mano.
// functions.php
add_action( 'init', function() {
register_block_type( get_template_directory() . '/blocks/testimonial' );
} );
Come scrivere l'Edit component e il Save in React?
L'Edit è un componente React che riceve le props: attributes, setAttributes, clientId. Dentro usi i componenti di @wordpress/components: RichText per contenuti, MediaUpload per immagini, InspectorControls per le impostazioni laterali.
// edit.js
import { __ } from '@wordpress/i18n';
import { useBlockProps, RichText, MediaUpload, InspectorControls } from '@wordpress/block-editor';
import { Button, PanelBody, TextControl } from '@wordpress/components';
export default function Edit({ attributes, setAttributes }) {
const { quote, author, avatarURL } = attributes;
return (
setAttributes({ avatarURL: media.url })}
render={({ open }) => (
)}
/>
{avatarURL &&
}
setAttributes({ quote: val })}
placeholder={__('Scrivi la citazione…', 'meteora')}
/>
setAttributes({ author: val })}
placeholder={__('Autore', 'meteora')}
/>
);
}
Il Save per blocco statico restituisce JSX che diventa l'HTML finale. Attenzione: non usare componenti React qui — solo markup puro.
Sponsored Protocol
// save.js
import { useBlockProps, RichText } from '@wordpress/block-editor';
export default function save({ attributes }) {
const { quote, author, avatarURL } = attributes;
return (
{avatarURL &&
}
{quote && {quote}
}
{author && {author}}
);
}
Errore comune: mettere logiche di stato o effetti nel save. Il save deve essere puramente dichiarativo. Se hai bisogno di dati live, usa un blocco dinamico con render.php.
Come gestire dati dinamici e richieste API dentro un blocco Gutenberg?
Spesso il blocco deve mostrare dati da un CPT, da un'API esterna o da un cache. In edit usi useSelect per query WordPress lato editor (senza server). Esempio: recuperare gli ultimi 5 post.
Sponsored Protocol
import { useSelect } from '@wordpress/data';
import { useBlockProps } from '@wordpress/block-editor';
export default function LatestPostsEdit() {
const posts = useSelect((select) => {
return select('core').getEntityRecords('postType', 'post', {
per_page: 5,
_embed: true,
});
}, []);
return (
{posts ? (
{posts.map((post) => (
-
{post.title.raw}
))}
) : (
Caricamento…
)}
);
}
Per richieste a servizi esterni (es. listino prezzi da un ERP), meglio usare la store API di WordPress e un endpoint custom nel tema. Noi abbiamo integrato blocchi che leggono il catalogo da API REST esterne — con caching lato server per evitare rallentamenti.
Come testare e ottimizzare un blocco Gutenberg custom?
Tooling: @wordpress/scripts fornisce webpack già configurato con JSX, SCSS e minification. Lancialo con npm start per sviluppo e npm run build per produzione. Noi aggiungiamo sempre eslint e prettier per codice pulito.
Sponsored Protocol
Performance: evita di caricare librerie React inutili. Il core WordPress include già React e wp-element. Il tuo bundle deve essere piccolo. Controlla con npm run build e verifica la dimensione del file.
Sicurezza: sanifica sempre gli attributi lato server. In render.php usa esc_html, esc_url. Non fidarti dell'input salvato. Lo vediamo spesso: blocchi custom che espongono XSS perché il testo non è scappato.
Accessibilità: usa RichText che gestisce già aria-label e focus. Aggiungi role e aria-* dove serve. Google penalizza i siti con blocchi inaccessibili? No, ma gli utenti sì.
Cosa fare adesso?
- Valuta se ti serve un blocco custom. Se il design richiede interazioni uniche o dati live, fallo. Se puoi usare i blocchi core (Cover, Columns, Group) con qualche CSS, risparmi tempo.
- Scarica @wordpress/create-block per generare lo scaffold. Comando:
npx @wordpress/create-block meteora-testimonial. Ti dà tutto pronto. - Leggi la documentazione ufficiale su WordPress Block Editor Handbook.
- Controlla i blocchi esistenti — spesso un blocco di terze parti può essere esteso con filtri. Noi preferiamo partire da zero per avere controllo totale, ma non è sempre necessario.
- Contattaci se vuoi che sviluppiamo blocchi su misura per la tua PMI. Partiamo dal problema, non dalla tecnologia. Vedi la nostra pagina dedicata a WordPress Avanzato.