WPForm 實作 utm 追蹤的方式

  1. 使用 hidden field 加入 utm 欄位

分別加入 utm_id, utm_campaign, utm_source, utm_medium, utm_term, utm_content

  1. 使用 PHP filter wpforms_field_properties_hidden 在所有隱藏欄位上多加上屬性
function wpf_field_properties_hidden( $properties, $field, $form_data ) {
    $properties[ 'inputs' ][ 'primary' ][ 'attr' ][ 'data-track' ] = $field['label'];
    return $properties;
}
add_filter( 'wpforms_field_properties_hidden', 'wpf_field_properties_hidden', 10, 3 );
  1. 在表單載入時,用 JavaScript 將資料灌入到 hidden field
<?php

add_action( 'wpforms_wp_footer_end', function () {
?>
<script type="text/javascript">
window.jQuery( document ).on('wpformsReady', function () {
    if (window.CookieSourceTracker) {
        const first = window.CookieSourceTracker.getCookie(window.CookieSourceTracker.containers.first)
        const current = window.CookieSourceTracker.getCookie(window.CookieSourceTracker.containers.current)

        if (current || first) {
            window.jQuery('[data-track=utm_id]').val(current.utm_id || first.utm_id)
            window.jQuery('[data-track=utm_source]').val(current.utm_source || first.utm_source)
            window.jQuery('[data-track=utm_medium]').val(current.utm_medium || first.utm_medium)
            window.jQuery('[data-track=utm_campaign]').val(current.utm_campaign || first.utm_campaign)
            window.jQuery('[data-track=utm_term]').val(current.utm_term || first.utm_term)
            window.jQuery('[data-track=utm_content]').val(current.utm_content || first.utm_content)
            window.jQuery('[data-track=referrer]').val(current.referrer || first.referrer)
            window.jQuery('[data-track=conversion_page]').val(current.url || first.url)
        }
    }
})
</script>
<?php
});

附錄 cookie source tracker

window.CookieSourceTracker = {

    containers: {
        first: 'cookie_source_tracker_first',
        current: 'cookie_source_tracker_current',
    },

    init: function() {

        let url = new URL(window.location.href);
        let params = new URLSearchParams(url.search);

        if (this.isCampaign()) {
            return this.setMainCookie({
                campaign: params.get('campaignid') || params.get('utm_campaign') || 'unknown_campaign',
                keyword: params.get('keyword')
            })
        }

        if (this.isEDM()) {
            return this.setMainCookie({
                campaign: 'EDM_' + params.get('utm_campaign')
            })
        }

        if (this.isSocial()) { 
            return this.setMainCookie({
                campaign: 'Social'
            })
        }

        if (this.isOrganic()) {
            return this.setMainCookie({
                campaign: 'Organic'
            })
        }

        if (this.isDirect()) {
            return this.setMainCookie({
                campaign: 'Direct'
            })
        }

        // 前面都沒有,設定為 None
        return this.setMainCookie({
            campaign: 'None'
        })
    },

    isSameDomain: function () {
        let referrer = document.referrer
        if (referrer) {
            try {
                let currentURL = new URL(window.location.href);
                let refererURL = new URL(referrer);
                return currentURL.hostname === refererURL.hostname
            } catch (e) {
                return false
            }
        }
        return false
    },

    isDirect: function () {
        return !document.referrer
    },

    isEDM: function () {
        let url = new URL(window.location.href);
        let params = new URLSearchParams(url.search);
        return params.get('utm_source') === 'EDM'
    },

    isCampaign: function () {
        let url = new URL(window.location.href);
        let params = new URLSearchParams(url.search);
        return params.get('utm_medium') === 'cpc'
            || params.get('utm_medium') === 'google_cpc'
            || params.get('gclid')
    },

    // Support Google, Bing, Yahoo, Yandex
    isOrganic: function () {
        if (document.referrer) {
            try {
                let referrerURL = new URL(document.referrer)
                return referrerURL.hostname.includes('yahoo.')
                    || referrerURL.hostname.includes('bing.')
                    || referrerURL.hostname.includes('google.')
                    || referrerURL.hostname.includes('yandex.')
            } catch (e) {
                return false
            }
        }
        return false
    },

    // Support Facebook, Instagram, Twitter, LinkedIn
    isSocial: function () {
        let url = new URL(window.location.href);
        let params = new URLSearchParams(url.search);
        return ['facebook', 'instagram', 'twitter', 'linkedin']
            .includes(params.get('utm_source'))
    },

    setMainCookie: function (cookeValue) {
        const url = new URL(window.location.href);
        const params = new URLSearchParams(url.search);
        const merged = Object.assign(cookeValue, {
            url: window.location.href,
            referrer: document.referrer,
            utm_id: params.get('utm_id'),
            utm_source: params.get('utm_source'),
            utm_medium: params.get('utm_medium'),
            utm_campaign: params.get('utm_campaign'),
            utm_term: params.get('utm_term'),
            utm_content: params.get('utm_content'),
        })

        if (!this.getCookie(this.containers.first)) {
            this.setCookie(this.containers.first, merged)
        }

        this.setCookie(this.containers.current, merged)
    },

    setCookie: function (cname, cvalue, exdays) {
        const d = new Date();
        d.setTime(d.getTime() + (exdays * 24 * 60 * 60 * 1000));
        let expires = "expires="+d.toUTCString();
        document.cookie = cname + "=" + JSON.stringify(cvalue) + ";" + expires + ";path=/";
    },

    getCookie: function (cname) {
        let name = cname + "=";
        let ca = document.cookie.split(';');
        for(let i = 0; i < ca.length; i++) {
            let c = ca[i];
            while (c.charAt(0) == ' ') {
                c = c.substring(1);
            }
            if (c.indexOf(name) == 0) {
                return JSON.parse(c.substring(name.length, c.length));
            }
        }
        return undefined
    }
}

window.CookieSourceTracker.init()