נכתב על ידי דני צ'רניאק, DigiKnowledge. נבדק לאחרונה: 24.10.2026

טופס Elementor Pro נשלח ב-AJAX, בלי טעינת עמוד, לכן הטריגר המובנה Form Submission של Google Tag Manager נורה על כל לחיצה על כפתור השליחה, גם כשהשרת דחה את הטופס. המדידה הנכונה נשענת על submit_success, אירוע jQuery שאלמנטור מפעיל על הטופס רק כשהתשובה מהשרת חזרה כהצלחה, אחרי הולידציה ואחרי כל פעולות ה-Actions After Submit. מאזין קצר בתג Custom HTML תופס את האירוע, דוחף ל-dataLayer אירוע generate_lead עם form_id ו-form_name בלי פרטים מזהים, חוסם כפילות בשליחה חוזרת באותו סשן. טריגר Custom Event מפעיל את תג GA4.

למה הטריגרים המובנים של GTM לא מספיקים לטופס Elementor?

כדי להבין את הבעיה צריך לעקוב אחרי מה שקורה בלחיצה על "שלח". קודם הדפדפן מריץ את הולידציה שלו: שדה חובה ריק או אימייל לא תקין עוצרים את השליחה עוד לפני שמשהו יוצא מהדפדפן. אם הולידציה עברה, הסקריפט של Elementor Pro תופס את אירוע ה-submit, מבטל את ההתנהגות הרגילה של הטופס ושולח בקשת POST ל-admin-ajax.php. בשרת, מחלקת ה-Ajax Handler של אלמנטור מריצה את הולידציה שלה (ה-hook בשם elementor_pro/forms/validation), מעבדת את השדות, מריצה את כל ה-Actions After Submit שהוגדרו בווידג'ט (Email, Collect Submissions, Webhook, Redirect ועוד), מפעילה את elementor_pro/forms/new_record ומחזירה JSON עם success ועם אובייקט data. רק אז הדפדפן מחליט: אם success הוא true, הטופס מפעיל את אירוע ה-jQuery submit_success, מאפס את השדות, מציג הודעה ירוקה או מפנה לעמוד תודה. אם success הוא false, מופיעה הודעה אדומה, השדות הבעייתיים מסומנים והטופס מפעיל אירוע error.

הטריגר Form Submission של GTM מקשיב לאירוע ה-submit של ה-DOM, שמתרחש לפני הבקשה לשרת. עם האפשרות Check Validation מסומנת הוא לא נורה לעולם, כי אלמנטור תמיד מבטלת את ההתנהגות הרגילה. בלי האפשרות הזו הוא נורה על כל ניסיון, כולל ניסיונות שהשרת דחה. טריגר Element Visibility על ההודעה הירוקה (elementor-message-success) קרוב יותר לאמת, אבל נשען על DOM: הודעה שהוסתרה ב-CSS, Redirect שמחליף את העמוד לפני שההודעה הוצגה או שתי הודעות באותו עמוד שוברים אותו בשקט. בפרויקטים שלנו הכלל הוא למדוד הצלחה לפי האות שהקוד עצמו מייצר, לא לפי מה שנראה על המסך.

מה קורה בכל תרחיש: הצלחה, שגיאת ולידציה ושליחה חוזרת?

הטבלה מפרטת את ארבעת המצבים שמבדיל ביניהם מאזין טוב. העמודות עוקבות אחרי השרשרת המלאה: מה הטופס עושה, מה נכנס ל-dataLayer, איזה טריגר נורה ב-GTM ומה מגיע בסוף ל-GA4. generate_lead_repeat ו-form_error הם השמות שאנחנו נותנים לאירועי העזר. אפשר לבחור אחרים, העיקר שלא יהיו generate_lead.

תרחישמה הטופס עושהמה קורה ב-dataLayerהטריגר ב-GTMמה נשלח ל-GA4
הצלחה, שליחה ראשונה בסשןהתשובה מהשרת היא success. אלמנטור מפעילה submit_success עם response.data, מאפסת את הטופס ומציגה הודעה ירוקה או מפנה ל-Redirect.המאזין בודק שאין דגל בסשן לטופס הזה, שומר דגל ודוחף event: generate_lead עם form_id, form_name ו-event_id חדש.Custom Event בשם generate_lead נורה פעם אחת.אירוע generate_lead עם הפרמטרים form_id ו-form_name, מסומן כ-Key Event. נספר ליד אחד.
שגיאת ולידציה בדפדפןשדה חובה ריק או פורמט לא תקין. הדפדפן עוצר את ה-submit, שום בקשה לא יוצאת.כלום. אלמנטור לא מפעילה אירוע, המאזין לא רץ.אף טריגר לא נורה. גם Form Submission המובנה לא נורה במקרה הזה.כלום. זה המצב הרצוי.
שגיאת ולידציה בשרתהולידציה בשרת נכשלה (hook מותאם, reCAPTCHA, Honeypot) או שפעולה החזירה שגיאה למשתמש. התשובה היא success false, הודעה אדומה, אירוע error.אין push של generate_lead. אופציונלי: push של form_error עם form_id, form_name ומספר השדות השגויים, בלי ערכי שדות.הטריגר generate_lead לא נורה. אופציונלי: Custom Event בשם form_error לתג אבחון.אין generate_lead. אופציונלי: form_error כאירוע רגיל, לא Key Event.
שליחה חוזרת באותו סשןהמשתמש ממלא שוב את אותו טופס אחרי הצלחה. אלמנטור מפעילה submit_success שוב, כי כל הצלחה מפעילה אותו.המאזין מוצא את הדגל בסשן ודוחף generate_lead_repeat עם event_id חדש במקום generate_lead.הטריגר generate_lead לא נורה. אופציונלי: טריגר ל-generate_lead_repeat.אין generate_lead שני. אופציונלי: generate_lead_repeat לניטור, לא Key Event.

הדיאגרמה מתארת את אותה שרשרת כזרימה: מהטופס, דרך התשובה מהשרת, ל-dataLayer, לטריגר ולתג. המסלול הסגול הוא הצלחה, המסלול הכתום הוא שגיאה, הפס התחתון הוא השליחה החוזרת.

זרימת מדידה

מהטופס ל-GA4: רק הצלחה הופכת ל-generate_lead

טופס Elementorשליחה ב-AJAX לשרת. ולידציה בשרת ואז Actions After Submit
הצלחה
submit_successresponse.success = true
הודעה ירוקה או Redirect
dataLayer.pushevent: generate_lead
form_id, form_name, event_id
בדיקת דגל הסשן לפני ה-push
GTM: טריגר Custom Eventשם האירוע: generate_lead
תג GA4 Eventפרמטרים form_id, form_name. אירוע מפתח
שגיאה
שגיאהresponse.success = false
הודעה אדומה, אירוע error
אין push של generate_leadאופציונלי: form_error
בלי ערכי שדות, בלי PII
הטריגר generate_lead לא נורהתג GA4 לא נשלח. הליד לא נספר
שליחה חוזרת באותו סשןsubmit_success נורה שוב, המאזין מוצא את הדגל ב-sessionStorage ודוחף generate_lead_repeat. הטריגר generate_lead לא נורה. event_id חדש לכל שליחה מאפשר דה-דופליקציה בצד שרת (sGTM, CRM) כשצריך.

מה ההבדל בין submit_success כאירוע jQuery לבין נתונים דרך Actions After Submit?

יש שני מסלולים להגיע לאותו push. הבחירה ביניהם תלויה בשאלה מי מייצר את המזהים ומי מחליט שהשליחה הצליחה. במסלול הראשון, הצד הקדמי בלבד, המאזין יושב בתג Custom HTML ב-GTM ונרשם עם jQuery(document).on('submit_success', '.elementor-form', function (e, data) {…}). הפרמטר e.target הוא אלמנט הטופס עצמו: ממנו קוראים את המאפיין name שמכיל את Form Name שהוגדר בווידג'ט ואת השדה החבוי form_id שמכיל את מזהה הווידג'ט. הפרמטר data הוא response.data שחזר מהשרת: הודעת ההצלחה ואובייקט data פנימי. חשוב לדעת שאלמנטור מפעילה את האירוע דרך jQuery.trigger, שלא יוצר אירוע DOM רגיל. לכן document.addEventListener('submit_success', …) לא תופס כלום. זו גם התשובה שצוות אלמנטור נותן בדיווחי באגים בנושא. היתרון של המסלול: אין קוד PHP, כל הלוגיקה בקונטיינר, ההטמעה נמשכת דקות. החיסרון: המזהים מגיעים מה-DOM, הדה-דופליקציה נשארת בדפדפן ואין מזהה שליחה שהשרת מכיר.

המסלול השני עובר דרך Actions After Submit. הפעולות האלה רצות בשרת, בתוך ה-Ajax Handler, אחרי הולידציה. בתיעוד המפתחים של אלמנטור פעולה מותאמת היא מחלקה שיורשת מ-Action_Base ומממשת run($record, $ajax_handler). אותו $ajax_handler זמין גם ב-hook elementor_pro/forms/new_record, שרץ אחרי שכל הפעולות הסתיימו. קריאה ל-$ajax_handler->add_response_data(key, value) מצרפת ערך לתשובת ה-JSON. הערך מגיע לדפדפן בתוך אותו אירוע submit_success, תחת data.data.key. ככה השרת מייצר event_id ייחודי לשליחה (wp_generate_uuid4), מחזיר את שם הטופס מההגדרות ושולח את אותו מזהה גם ל-CRM או ל-Webhook. היתרון: מזהה אחד לשליחה אחת, בדפדפן ובשרת, שמאפשר דה-דופליקציה מול Meta CAPI או מול המרות אופליין. החיסרון: צריך מפתח, תוסף קטן או child theme ובדיקה אחרי כל עדכון של Elementor Pro.

ההמלצה שלנו: המסלול הראשון הוא הבסיס לכל אתר Elementor, המסלול השני נוסף כשיש קונטיינר שרת, חיבור ל-CRM או דרישה להתאים ליד בדפדפן לליד במערכת. שני המסלולים מסתיימים באותו אירוע generate_lead ב-dataLayer, כך שצד ה-GTM זהה. המאזין בקוד למטה כבר יודע לקבל event_id מהשרת אם הוא קיים ולייצר אחד בעצמו אם לא.

איך מטמיעים את זה ב-GTM, שלב אחרי שלב?

  1. שם לכל טופס. בווידג'ט הטופס, בשדה Form Name, נותנים שם קריא וייחודי לכל טופס באתר, למשל contact_main או quote_pricing. הערך הזה הופך ל-form_name ב-GA4. form_id הוא מזהה הווידג'ט, שמשתנה כשמעתיקים את הווידג'ט, לכן השם הוא המפתח לדיווח והמזהה הוא גיבוי.
  2. תג המאזין. תג Custom HTML עם הקוד למטה. הטריגר הוא Window Loaded, כי jQuery וסקריפט הטפסים של אלמנטור נטענים בפוטר. תג שרץ ב-Container Loaded עשוי לרוץ לפני שהם קיימים. הקוד בודק שיש jQuery ושהמאזין לא נרשם כבר.
  3. משתני Data Layer. שלושה משתנים מסוג Data Layer Variable, גרסה 2: form_id, form_name, event_id.
  4. טריגר Custom Event. שם האירוע generate_lead, בלי regex, על כל האירועים המותאמים.
  5. תג GA4 Event. שם האירוע generate_lead, פרמטרים form_id ו-form_name ממופים למשתנים. event_id נשלח כפרמטר רק אם יש קונטיינר שרת או ייצוא ל-BigQuery שמשתמש בו. הגדרות ההסכמה כמו בשאר תגי GA4 באתר.
  6. GA4 Admin. רושמים form_name ו-form_id כ-Custom Dimensions ברמת אירוע ומסמנים את generate_lead כ-Key Event. בלי הרישום הפרמטרים נראים ב-DebugView אבל לא בדוחות.
  7. אופציונלי, המסלול השרתי. מפתח מוסיף את קטע ה-PHP למטה. מהרגע שהוא פעיל, המאזין משתמש ב-event_id שהגיע מהשרת.

הקוד לתג המאזין. ההערות בעברית הן חלק מהקוד ואפשר להשאיר אותן.

<script>
(function () {
  if (!window.jQuery || window.__dkLeadListener) { return; }
  window.__dkLeadListener = true;            // המאזין נרשם פעם אחת בלבד
  window.dataLayer = window.dataLayer || [];

  jQuery(document).on('submit_success', '.elementor-form', function (e, data) {
    var $form = jQuery(e.target);
    var formId = String($form.find('input[name="form_id"]').val() || 'unknown');
    var formName = e.target.getAttribute('name') || 'elementor_form';
    var serverData = (data && data.data) || {};
    var eventId = serverData.dk_event_id ||
      (Date.now().toString(36) + '-' + Math.random().toString(36).slice(2, 10));
    var key = 'dk_lead_' + formId;
    var sentBefore = false;

    try { sentBefore = sessionStorage.getItem(key) === '1'; } catch (err) {}

    if (sentBefore) {                         // שליחה חוזרת באותו סשן
      window.dataLayer.push({ event: 'generate_lead_repeat',
        form_id: formId, form_name: formName, event_id: eventId });
      return;
    }
    try { sessionStorage.setItem(key, '1'); } catch (err) {}

    window.dataLayer.push({                   // ליד ראשון: בלי ערכי שדות, בלי PII
      event: 'generate_lead',
      form_id: formId,
      form_name: formName,
      event_id: eventId
    });
  });

  jQuery(document).on('error', '.elementor-form', function (e) {
    var $form = jQuery(e.target);             // שגיאה מהשרת: אירוע אבחון בלבד
    window.dataLayer.push({
      event: 'form_error',
      form_id: String($form.find('input[name="form_id"]').val() || 'unknown'),
      form_name: e.target.getAttribute('name') || 'elementor_form',
      error_count: $form.find('.elementor-error').length
    });
  });
})();
</script>

קטע ה-PHP למסלול השרתי, לתוסף קטן או ל-functions.php של child theme. הוא מצרף לתשובה מזהה ייחודי ואת שם הטופס מההגדרות.

add_action( 'elementor_pro/forms/new_record', function ( $record, $ajax_handler ) {
    $settings = $record->get( 'form_settings' );
    $ajax_handler->add_response_data( 'dk_event_id', wp_generate_uuid4() );
    $ajax_handler->add_response_data( 'dk_form_name', $settings['form_name'] ?? '' );
}, 10, 2 );

אם רוצים שאותו מזהה יגיע גם ל-Webhook או למייל, מייצרים אותו ב-hook מוקדם יותר, elementor_pro/forms/process שרץ לפני הפעולות. שם שומרים אותו ברשומה. new_record רץ אחרי שהפעולות הסתיימו, לכן הוא מתאים להחזרת נתונים לדפדפן ולא להזנת הפעולות עצמן.

מניעת כפילות: דגל בסשן או event_id?

יש שתי שכבות של כפילות ושתי הגנות שונות. השכבה הראשונה היא רישום כפול של המאזין: תג שנורה פעמיים (Window Loaded ועוד History Change, או שני קונטיינרים באותו עמוד) רושם שני מאזינים. כל שליחה מייצרת אז שני push. הדגל window.__dkLeadListener סוגר את זה. השכבה השנייה היא שליחה חוזרת אמיתית: אותו משתמש שולח את אותו טופס פעמיים באותו ביקור, אחרי הודעת הצלחה. הדגל ב-sessionStorage, לפי form_id, הופך את השליחה השנייה ל-generate_lead_repeat. sessionStorage נמחק כשהלשונית נסגרת, לכן ביקור חדש מתחיל נקי, בדומה לסשן ב-GA4.

event_id משלים את הדגל ולא מחליף אותו. GA4 לא מבצע דה-דופליקציה לפי event_id, אבל המזהה מאפשר לאחד שורות ב-BigQuery, להתאים ליד בדפדפן לליד בשרת ולשלוח אותו מזהה ל-Meta דרך הפיקסל ו-CAPI. באתרים שבהם שליחה חוזרת היא לגיטימית, למשל טופס שמבקשים דרכו כמה הצעות מחיר שונות, מורידים את דגל הסשן, שומרים על event_id ומנהלים את הספירה בדיווח. שיטת הספירה של Key Event ב-GA4 (פעם לאירוע או פעם לסשן) היא רשת ביטחון אחרונה, לא תחליף לטיפול במקור.

למה בלי PII?

תנאי השימוש של Google Analytics אוסרים לשלוח מידע מזהה כמו שם, אימייל וטלפון. לכן ה-push מכיל רק את מזהי הטופס ולא את ערכי השדות, גם לא בגיבוב. כשצריך Advanced Matching ל-Meta, זה עובר דרך השדות הייעודיים של תבנית התג של Meta ובכפוף להסכמה, לא דרך אירוע GA4. בפרויקטים שלנו המאזין לא נוגע בשדות שהמשתמש מילא, רק באלמנט הטופס ובשדות החבויים של אלמנטור.

טעויות נפוצות

הטעות הראשונה היא ספירת ניסיונות במקום הצלחות: טריגר Form Submission או טריגר Click על כפתור השליחה. התוצאה היא פער קבוע מול מספר הרשומות ב-Submissions של אלמנטור או ב-CRM, שגדל ככל שהטופס מקבל יותר שגיאות. הטעות השנייה היא מאזין שלא נרשם: document.addEventListener לאירוע jQuery, או תג Custom HTML שרץ ב-Container Loaded לפני ש-jQuery נטען ונופל על jQuery is not defined. בשני המקרים לא נמדד שום ליד, מה שנראה כמו ירידה חדה בהמרות אחרי "שיפור" המדידה.

הטעות השלישית היא מדידה כפולה של אותו ליד: תג GA4 שמחובר גם לטריגר generate_lead וגם לטריגר Form Submission ישן שנשאר בקונטיינר, או ליד שנמדד גם ב-submit_success וגם ב-page_view של עמוד התודה אחרי Redirect. בוחרים מקור אחד. הטעות הרביעית היא דגל סשן גלובלי, בלי form_id, שחוסם את הטופס השני באותו עמוד כי הראשון כבר נשלח. הטעות החמישית היא דחיפת ערכי שדות ל-dataLayer "בשביל ה-CRM". זה PII בתוך GA4 וגם קוד שנשבר בכל שינוי בשדות הטופס. הטעות השישית היא טריגר Element Visibility על הודעת ההצלחה בלי Once per page, שנורה שוב בכל פעם שההודעה חוזרת ל-viewport, או שלא נורה בכלל כשיש Redirect מהיר.

איך בודקים שזה עובד?

בדיקת הקבלה הראשונה היא ב-Preview של GTM, דרך Tag Assistant. מתחברים לעמוד הטופס, ממלאים נתוני דמו תקינים ושולחים. בציר הזמן של Tag Assistant צריך להופיע אירוע generate_lead אחרי שהתשובה חזרה מהשרת. בלשונית Data Layer רואים את ה-push המלא עם form_id, form_name ו-event_id, בלשונית Variables רואים שהמשתנים התמלאו ובלשונית Tags רואים שתג ה-GA4 נורה פעם אחת בלבד. אם תג המאזין נורה אבל generate_lead לא מופיע, פותחים את הקונסול ומוודאים שאין שגיאת jQuery.

הבדיקה השנייה היא ב-DebugView של GA4. כש-Preview פעיל, Tag Assistant מוסיף לכתובת פרמטר דיבאג, כך שהאירועים מהדפדפן הזה מגיעים ל-DebugView. בזרם השניות צריך להופיע generate_lead. בלחיצה עליו רואים את הפרמטרים form_id ו-form_name עם הערכים הנכונים. אם האירוע כבר סומן כ-Key Event, הוא מופיע עם סימון מתאים. בדיקה שלישית היא תרחיש השגיאה: שולחים טופס עם שדה חובה ריק ומוודאים שאין שום אירוע בציר הזמן. אחר כך מייצרים שגיאת שרת, למשל עם reCAPTCHA לא תקין או כלל ולידציה מותאם. בודקים שמופיעה הודעה אדומה, שמופיע form_error ושתג GA4 של generate_lead לא נורה.

הבדיקה הרביעית היא השליחה החוזרת. באותה לשונית שולחים את אותו טופס שוב. בציר הזמן צריך להופיע generate_lead_repeat ולא generate_lead. תג ה-GA4 לא נורה. בלשונית חדשה הדגל מתאפס והשליחה נמדדת כליד. הבדיקה החמישית, שבוע אחרי הפרסום, היא השוואה: סופרים את Key Events של generate_lead ב-GA4 לפי form_name ומשווים למספר הרשומות ב-Submissions של אלמנטור או במערכת שמקבלת את הלידים באותם ימים. פער של אחוזים בודדים הוא נורמלי בגלל חוסמי פרסומות וסירוב להסכמה. פער של כפול מעיד על מאזין כפול, פער של חצי על מאזין שלא נרשם בחלק מהעמודים.

מה לקחת מכאן?

הטופס של Elementor מודיע בעצמו מתי הוא הצליח, דרך submit_success. אין סיבה למדוד לפי לחיצות או לפי הודעה שמופיעה על המסך. מאזין אחד, בדיקת כפילות אחת ו-push נקי של generate_lead עם form_id ו-form_name נותנים ל-GA4 מספר שאפשר להשוות למספר הלידים האמיתי. אם אתם רוצים שנעבור על הקונטיינר שלכם ונבדוק איך הטפסים נמדדים היום, אפשר לקרוא על שירות ה-Tag Manager שלנו, על הטמעת GA4 ו-Key Events, או לפנות אלינו ישירות.

מדריכים קשורים

נטישת טפסים ב-GA4: איך מודדים התחלה ושליחה ואיפה נוטשים
מעקב קליקים ב-GTM: קישורים יוצאים, כפתורים, tel ו-mailto
מעקב גלילה וצפייה בוידאו YouTube ב-GTM: הטריגרים המובנים והמגבלות

מקורות

דני צ'רניאק
דני צ'רניאק
יועץ אנליטיקה דיגיטלית ומייסד DigiKnowledge. מרצה לאנליטיקה דיגיטלית באוניברסיטת תל אביב, באוניברסיטה הפתוחה ובאוניברסיטת אריאל. לעמוד האישי