Salta ai contenuti

WordPress headless

WordPress è il backoffice, non il sito. Il frontend legge la REST API in fase di build e produce file statici. Il browser dell’utente non parla mai con WordPress.

I must-use plugin sono plugin sempre attivi, caricati automaticamente da wp-content/mu-plugins/. Non hanno attivazione, non si disattivano per errore, non dipendono dal tema.

Nel template ce ne sono quattro:

File Cosa fa
headless-cms.php registra CPT, custom meta, pannello impostazioni e rotta /headless/v1/settings
headless-contact.php CPT contatto, rotta POST /headless/v1/contact, invio email
headless-webhook.php notifica GitHub al salvataggio dei contenuti (rebuild)
headless-disable-xmlrpc.php disattiva XML-RPC

Niente ACF, CMB2 o Pods: i campi sono registrati con le API native (register_post_type, register_post_meta, add_meta_box). Meno dipendenze, meno superficie, contratto esplicito.

Ogni CPT corrisponde a una collezione Astro in src/content.config.ts.

CPT Collezione Dove appare
evento eventi home, /eventi, dettaglio evento
tariffa tariffe listino in home
promo promos promozioni in home
faq faqs FAQ in home
partner partner carosello loghi
collaboratore collaboratori team in /chi-siamo
timeline_entry timeline storia in /chi-siamo
spazio spazi galleria in home
page (nativo) pagine hero image/video delle pagine
impostazioni siteSettings footer, contatti, form, cookie
Endpoint Uso
/wp-json/wp/v2/{cpt} una richiesta per collezione, per_page=100
/wp-json/wp/v2/media?include=... risoluzione batch degli ID immagine
/wp-json/wp/v2/pages hero delle pagine native
/wp-json/headless/v1/settings contatti, social, URL legali, toggle sezioni
POST /wp-json/headless/v1/contact form contatti

In Impostazioni → Impostazioni sito si gestiscono:

  • dati fiscali (P.IVA, CF, SDI) — se vuoti il footer li nasconde;
  • indirizzo, telefono, email, WhatsApp;
  • Instagram, Facebook, LinkedIn;
  • URL di Privacy, Cookie e Termini;
  • toggle per Promozioni, Tariffe, FAQ.

I valori sono opzioni headless_* e vengono esposti pubblicamente in sola lettura. Il frontend li legge con getSiteSettings(), che applica i fallback di src/data/site.ts.

  1. L’editor crea o modifica un contenuto in WordPress.
  2. Al salvataggio il mu-plugin webhook fa una repository_dispatch a GitHub.
  3. Il workflow deploy.yml rifà build e deploy.
  4. Il sito pubblico mostra i nuovi contenuti.

Non c’è anteprima: la modifica si vede dopo il rebuild. È il compromesso dello statico, spiegato in Build e concorrenza.

Pubblico (sola lettura):

  • i CPT e i loro meta: servono alla build;
  • le impostazioni sito;
  • la rotta di contatto in POST (protetta da validazione, honeypot e rate limit).

Non pubblico:

  • scrittura dei contenuti (protetta dalle capability di WordPress);
  • il CPT contatto (public: false, show_in_rest: false);
  • XML-RPC (disattivato);
  • credenziali e token (in wp-config.php, mai nel repository).

auth_callback => '__return_true' sui meta serve solo a permettere la lettura pubblica in REST. La scrittura passa dai controlli di WordPress (edit_post).

  • CTP → contenuti ripetuti e strutturati (eventi, tariffe, team).
  • Pagine native → solo per l’hero delle pagine Astro (immagine/video). I testi fissi delle pagine restano nel codice, così la struttura non dipende dall’editor.

Se un cliente vuole cambiare un testo di una pagina senza sviluppatore, quel testo deve diventare un campo (CPT o impostazione), non un paragrafo nell’editor.

I campi immagine salvano l’ID del media, non l’URL. Il loader risolve gli ID in URL con una richiesta batch. Se in admin incolli un URL, l’immagine non compare: è l’errore più comune.

  • Nessun tema custom usato dal pubblico.
  • Nessun page builder (Elementor, WPBakery…).
  • Nessun contenuto renderizzato da WordPress nel frontend.
  • Nessun plugin che cambi la REST in modo implicito.