
🐛 Contact Form 7 nel popup di Elementor: perché il modulo ricarica la pagina e come risolverlo
Aggiungi un modulo di contatto tramite Contact Form 7 all'interno di un popup di Elementor Pro. L'utente compila i campi, clicca su «Invia» e l'intera pagina si ricarica.
Nessun messaggio di errore. Nessuna conferma di invio. Solo un reload e un lead perso.
Si tratta di un conflitto noto: CF7 si basa sull'invio AJAX, ma all'interno di un popup caricato dinamicamente il suo JavaScript non ha il tempo di agganciarsi al modulo. Di conseguenza, il browser esegue un submit HTML standard, proprio quello che causa il reload.
Il problema esiste da anni, eppure si risolve con due sole righe di codice. Ecco due soluzioni funzionanti: una moderna (più pulita e affidabile) e un'alternativa presa da GitHub, più alcuni miglioramenti opzionali e una checklist di debug.
💡 Panoramica rapida:
- Causa principale: CF7 si inizializza al caricamento della pagina, ma il popup con il modulo appare dopo, quindi lo script non sa nulla del suo contenuto
- Soluzione 1: reinizializzare CF7 quando si attiva l'evento
elementor/popup/show; JavaScript attende l'apertura del popup e aggancia il modulo - Soluzione 2: tracciare i click sul pulsante che apre il popup con un ritardo per l'animazione; questo metodo proviene da una discussione su GitHub relativa a Elementor
- Opzionale: resettare il modulo alla riapertura e chiudere automaticamente il popup dopo un invio riuscito
- Checklist di debug: console del browser, conflitti jQuery, plugin di caching
Perché CF7 si rompe proprio in un popup

Contact Form 7 è basato su AJAX: il modulo si invia senza ricaricare la pagina, la validazione dei campi avviene al volo e i messaggi di errore o successo appaiono all'istante. Tuttavia, l'intero meccanismo si aggancia al DOM al caricamento della pagina tramite una chiamata a wpcf7.init().
Elementor Pro carica il contenuto del popup dinamicamente, dopo l'evento DOMContentLoaded. Quando un utente clicca un pulsante e il popup si apre, il suo HTML viene inserito nel documento, ma CF7 non ne sa nulla. Il modulo all'interno del popup resta non inizializzato.
Cosa succede a questo punto: senza un gestore AJAX attivo, il browser esegue un invio standard del modulo HTML. L'attributo action viene attivato e la pagina si ricarica. Il popup si chiude naturalmente (il suo stato si resetta alla navigazione). L'utente vede un reload e se ne va.
Molti sviluppatori cercano di trattare i sintomi: bloccano la chiusura del popup con event.stopPropagation(), sovrascrivono funzioni interne di Elementor o impediscono l'invio del modulo con e.preventDefault(). Nessuno di questi metodi affronta la causa reale (la mancata inizializzazione di CF7). Alcuni arrivano persino a rompere le animazioni del popup o Elementor stesso sull'intero sito.
C'è una sola soluzione affidabile: attendere l'apertura del popup e chiamare esplicitamente wpcf7.init() per ogni modulo al suo interno.
Soluzione 1: reinizializzazione all'apertura del popup (approccio moderno)
Questo metodo utilizza l'evento nativo di Elementor elementor/popup/show. Inserisci il codice nel file functions.php del tuo tema attivo o aggiungilo tramite un plugin per snippet come Code Snippets.
Crea un backup di functions.php prima di modificarlo.
1 /** 2 * Reinitialize Contact Form 7 when opening an Elementor popup. 3 * Fixes page reload after form submission. 4 */ 5 function sdstudio_cf7_reinit_in_popup() { 6 ?> 7 <script> 8 jQuery( document ).on( 'elementor/popup/show', function() { 9 document.querySelectorAll( '.wpcf7 form' ).forEach( function( form ) { 10 if ( typeof wpcf7 !== 'undefined' ) { 11 wpcf7.init( form ); 12 } 13 }); 14 }); 15 </script> 16 <?php 17 } 18 add_action( 'wp_footer', 'sdstudio_cf7_reinit_in_popup' );
Dopo aver salvato, apri il popup con il modulo e testalo: compila i campi obbligatori in modo errato e clicca «Invia». I messaggi di validazione dovrebbero apparire all'istante senza ricaricare la pagina. Poi invia il modulo correttamente e verifica che anche il messaggio di successo venga mostrato all'interno del popup.
Il codice attende l'evento elementor/popup/show, che viene garantito dopo il rendering del contenuto del popup. Poi querySelectorAll trova tutti i moduli CF7 nel DOM corrente e wpcf7.init() aggancia forzatamente la validazione e l'invio AJAX a ciascuno di essi. Il controllo typeof wpcf7 !== 'undefined' protegge da errori se CF7 non è stato caricato per qualche motivo.
Soluzione 2: tracciare i click sul pulsante del popup (metodo alternativo)
Questo approccio è stato pubblicato nella discussione GitHub di Elementor #7798 dall'utente @drinkmaker. Invece di tracciare l'apertura del popup, monitora i click su un pulsante o link con href='#elementor-action', che è esattamente il modo in cui Elementor attiva i popup.
Il ritardo setTimeout(..., 800) concede il tempo per l'animazione di comparsa del popup prima che il codice trovi e inizializzi il modulo. Il marcatore .elementor impedisce di reinizializzare due volte lo stesso modulo.
1 /** 2 * Alternative initialization of CF7 in Elementor popups. 3 * Source: https://github.com/elementor/elementor/issues/7798 (drinkmaker) 4 */ 5 function sdstudio_elementor_cf7_alt_init() { 6 ?> 7 <script type='text/javascript'> 8 jQuery( document ).ready( function() { 9 10 jQuery( document ).on( 'click', "a[href='#elementor-action']", function() { 11 12 setTimeout( function() { 13 14 jQuery( '.elementor-popup-modal form.wpcf7-form:not(.elementor)' ).each( function( index ) { 15 wpcf7.initForm( jQuery( this ) ); 16 jQuery( this ).addClass( 'elementor' ); 17 }); 18 19 }, 800 ); 20 21 }); 22 23 }); 24 </script> 25 <?php 26 } 27 add_action( 'wp_footer', 'sdstudio_elementor_cf7_alt_init' );
Quale metodo scegliere: il primo (che usa l'evento elementor/popup/show) è preferibile perché si basa sull'API documentata di Elementor, è più pulito e non dipende da timeout. Il secondo è stato testato sul campo in produzione per anni e rappresenta un affidabile piano B se il primo non dovesse funzionare per qualche ragione.
Opzionale: resettare il modulo alla riapertura
Quando un utente chiude il popup e lo riapre, i campi del modulo restano compilati. Questo genera confusione: non è chiaro se il modulo sia stato inviato o meno. Una piccola aggiunta alla prima soluzione risolve il problema:
1 /** 2 * Reset CF7 form each time an Elementor popup opens. 3 */ 4 function sdstudio_cf7_reset_on_popup_open() { 5 ?> 6 <script> 7 jQuery( document ).on( 'elementor/popup/show', function() { 8 jQuery( '.wpcf7 form' ).each( function() { 9 this.reset(); 10 jQuery( this ).find( '.wpcf7-not-valid' ).removeClass( 'wpcf7-not-valid' ); 11 jQuery( this ).find( '.wpcf7-response-output' ).hide(); 12 jQuery( this ).find( '.wpcf7-not-valid-tip' ).remove(); 13 }); 14 }); 15 </script> 16 <?php 17 } 18 add_action( 'wp_footer', 'sdstudio_cf7_reset_on_popup_open' );
La funzione resetta i valori dei campi con reset(), rimuove le classi CSS dai campi non validi, nasconde i messaggi di invio e rimuove i suggerimenti di validazione. L'utente vede sempre un modulo pulito.
Opzionale: chiudere il popup dopo un invio riuscito
Dopo un invio andato a buon fine, ha senso chiudere automaticamente il popup dopo 1,5 secondi, in modo che l'utente abbia il tempo di leggere la conferma senza dover cercare il pulsante di chiusura:
1 /** 2 * Auto-close Elementor popup after successful CF7 submission. 3 */ 4 function sdstudio_close_popup_on_cf7_success() { 5 ?> 6 <script> 7 document.addEventListener( 'wpcf7mailsent', function() { 8 setTimeout( function() { 9 jQuery( '.dialog-close-button' ).trigger( 'click' ); 10 }, 1500 ); 11 }, false ); 12 </script> 13 <?php 14 } 15 add_action( 'wp_footer', 'sdstudio_close_popup_on_cf7_success' );
L'evento wpcf7mailsent si attiva quando il server conferma che l'email è stata inviata. Il ritardo di 1500 ms dà all'utente il tempo di leggere il messaggio di successo. Il click su .dialog-close-button utilizza il pulsante di chiusura standard di Elementor. A differenza dei tentativi di chiamare direttamente l'API del popup, questo metodo è stabile su tutte le versioni.
Checklist di debug
Se il modulo ricarica ancora la pagina dopo aver aggiunto il codice, segui questi passaggi:
Console del browser. Apri DevTools (F12 → Console) e verifica la presenza di errori JavaScript in rosso. Una causa comune è jQuery che non viene caricato o che entra in conflitto con un altro plugin.
Caching. Plugin come WP Rocket, Autoptimize o la cache a livello di host possono minificare e combinare gli script. Disattiva temporaneamente l'ottimizzazione aggressiva dei JS e testa di nuovo.
jQuery in modalità noConflict. Se un tema o un plugin racchiude jQuery in
noConflict, sostituiscijQuerycon$usando un wrapper appropriato, oppure utilizza la forma estesajQuery.ID del popup. Assicurati che il modulo sia all'interno del popup esatto attivato da un pulsante con
href='#elementor-action'. Per i popup aperti con altri tipi di trigger (ad esempio, a tempo), il primo metodo conelementor/popup/showè più affidabile.Conflitto tra plugin. Disattiva gli altri plugin uno per uno e testa, specialmente quelli che aggiungono i propri script di validazione o modificano il comportamento dei moduli.
Versione di CF7. Queste soluzioni sono state testate su Contact Form 7 versione 5.7+ e Elementor Pro 3.5+. Se la tua versione di CF7 è inferiore alla 5.7, la funzione
wpcf7.init()potrebbe avere un nome diverso; aggiorna il plugin.
⁉️🤔 Domande frequenti
Perché CF7 funziona su una pagina normale ma si rompe in un popup?
Quando una pagina normale si carica, il DOM è già costruito e CF7 ha il tempo di inizializzare tutti i moduli. Il popup di Elementor carica il contenuto in modo asincrono, dopo che CF7 ha terminato il suo lavoro. Il modulo finisce nel DOM ma senza un gestore JavaScript associato. Ecco perché verificare che «funziona su una pagina separata» non aiuta: le condizioni di caricamento sono radicalmente diverse. La soluzione è sempre la reinizializzazione forzata all'apertura del popup, indipendentemente dal fatto che il modulo funzioni altrove.
Posso cavarmela senza codice, usando un plugin o un'impostazione?
Non esiste un plugin già pronto che permetta di «spuntare una casella e far funzionare tutto» per questo bug. Il problema si trova all'intersezione tra due prodotti indipendenti (Elementor e CF7), e ciascuno funziona correttamente da solo. Add-on di terze parti come WPB Popup for Contact Form 7 risolvono il problema in modo diverso: creano popup propri invece di correggere Elementor. Il codice sopra è l'intervento minimo necessario. Lo aggiungi una volta al
functions.phpe non richiede aggiornamenti quando escono nuove versioni di CF7 o Elementor.
Il primo metodo non ha funzionato. Cosa devo controllare prima di passare al secondo?
Verifica tre cose. Primo: l'evento
elementor/popup/showè disponibile a partire da Elementor Pro 2.7; se la tua versione è inferiore, usa subito il secondo metodo. Secondo: apri la console e digitatypeof wpcf7; se restituisceundefined, il plugin CF7 non ha caricato il suo JavaScript (cerca errori o conflitti). Terzo: assicurati che il modulo all'interno del popup abbia la classe.wpcf7; senza di essa, il selettorequerySelectorAll('.wpcf7 form')non troverà nulla. Nella stragrande maggioranza dei casi, il primo metodo funziona immediatamente. In caso contrario, usa il secondo: è stato provato su centinaia di siti nel corso degli anni.
Devo aggiungere tutti e tre gli snippet o ne basta uno?
Il primo snippet (reinizializzazione) è il minimo indispensabile. Il secondo è un'alternativa; aggiungilo solo se il primo non ha risolto il problema. Il reset del modulo e la chiusura automatica del popup sono miglioramenti opzionali che puoi aggiungere secondo necessità: il reset è utile se il popup si apre più volte durante una singola visita; la chiusura automatica è comoda se il popup è usato per richieste e non contiene testi di conferma lunghi. Tutti e tre gli snippet sono indipendenti e possono funzionare contemporaneamente. Non ci sono conflitti tra loro.
Dopo la correzione, il modulo invia ma le email non arrivano. È correlato?
No, i problemi di recapito delle email sono un tema separato, non correlato al funzionamento di CF7 all'interno di un popup. Se dopo aver applicato la correzione il modulo mostra un messaggio di successo (bordo verde), l'invio AJAX funziona correttamente. Email non ricevute: verifica le impostazioni SMTP, i filtri antispam dell'hosting e l'indirizzo del destinatario nelle impostazioni del modulo CF7. Per un recapito affidabile, usa un plugin SMTP come Post SMTP o FluentSMTP invece della funzione standard
wp_mail(), poiché gli host spesso bloccano la posta PHP in uscita.
Questa soluzione influisce sugli altri moduli CF7 del sito?
No. Entrambi i metodi sono isolati: il primo attende l'apertura di un popup Elementor, il secondo traccia solo i link con
href='#elementor-action'. I moduli CF7 normali inseriti in pagine e widget continuano a funzionare normalmente; vengono inizializzati al caricamento della pagina e restano inalterati. Unica avvertenza: se il tuo sito usa un caching aggressivo con concatenazione degli script, aggiungi il codice del popup alle esclusioni della minificazione per evitare una doppia esecuzione.
Vale la pena usare codice personalizzato nel 2026
Entrambi i plugin, Contact Form 7 e Elementor Pro, sono attivamente sviluppati e aggiornati. CF7 mantiene la sua posizione come plugin per moduli WordPress più popolare con oltre 5 milioni di installazioni attive. Elementor Pro è usato su un sito WordPress su quattro.
Eppure il bug qui descritto non è stato risolto a livello di core di nessuno dei due plugin e probabilmente non lo sarà mai. La ragione è architetturale: CF7 è responsabile dei moduli, Elementor è responsabile del contenuto dinamico e l'inizializzazione degli script nel DOM caricato dinamicamente resta una responsabilità dello sviluppatore.
La buona notizia: la correzione è banale, il codice si aggiunge una volta sola e non richiede manutenzione. Scegli il primo metodo (l'evento elementor/popup/show): è il più pulito e puoi dimenticarti del problema. Se il modulo nel popup è usato per scenari critici di lead generation, aggiungi anche il reset dei campi e la chiusura automatica: l'esperienza utente migliorerà sensibilmente.
Guarda il video qui sopra: mostra l'intero processo di configurazione di un popup con Contact Form 7 in Elementor. Questa guida visiva passo passo completa gli snippet forniti qui e ti aiuta a evitare errori durante l'assemblaggio.



