Created
July 12, 2024 21:39
-
-
Save grayayer/d26f27b82931a82691bb35f4e9116be7 to your computer and use it in GitHub Desktop.
This provides extra data that GA4 doesn't provide on it's own.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Global Constants to use throughout the script | |
const pageTitle = document.title; | |
const pageUrl = window.location.href; | |
window.addEventListener('load', () => { | |
//## FORMS ### | |
const forms = document.querySelectorAll('form:not([data-type="search"])'); | |
if([...forms].length > 0){ | |
forms.forEach((form) => { | |
form.addEventListener('submit', (e) => { | |
e.preventDefault(); // prevent the form from submitting immediately | |
// Get create variables for the parameters we want to send to GA4 | |
const formId = e.target.id; | |
// send event to GA4 | |
gtag('event', 'solo_form_submit', { | |
'event_category': 'form', | |
'page_title': pageTitle, | |
'page_location': pageUrl, | |
'form_id': formId | |
}); | |
}); | |
}); | |
} | |
}); | |
// RELATED RESOURCES CTAS ####### | |
// the extra check here is to ensure that this doesn't run on the resources page itself or an immediate child of it, but do run on all other pages | |
var currentPath = window.location.pathname; | |
// Count the number of slashes in the pathname | |
var slashCount = currentPath.split('/').length - 1; | |
if(!currentPath.startsWith('/resources/') || (currentPath.startsWith('/resources/') && slashCount > 3)) { | |
const relatedResourceCTA = document.querySelectorAll('a.resource-card, .related-resources a.item'); | |
if([...relatedResourceCTA].length > 0){ | |
relatedResourceCTA.forEach((relatedResourceCTA) => { | |
// console.log(relatedResourceCTA); sanity check | |
relatedResourceCTA.addEventListener('click', (e) => { | |
const resourceTitle = e.currentTarget.getAttribute('data-title'); | |
const resourceType = e.currentTarget.getAttribute('data-type'); | |
// send event to GA4 | |
gtag('event', 'solo_CTA_click', { | |
'event_category': 'click', | |
'cta_category': 'resource', | |
'page_title': pageTitle, | |
'page_location': pageUrl, | |
'resource_title': resourceTitle, | |
'resource_type': resourceType | |
}); | |
}); | |
}); | |
} | |
} | |
// if the current page starts with /blog/ but isn't the blog index page, then look for the javascript variables for custom dimensions and send that to GA4 | |
if(currentPath.startsWith('/blog/') && currentPath !== '/blog/'){ | |
// send event to GA4 | |
gtag('event', 'page_view', { | |
'post_topic': postTopic, | |
'post_author': postAuthor | |
}); | |
} | |
// track all button clicks that have the class of .btn, | |
// but exclude all buttons that have a type of submit, or have a data-track attribute of false | |
const buttons = document.querySelectorAll('.btn:not([type="submit"]):not([data-track="false"])'); | |
if([...buttons].length > 0){ | |
buttons.forEach((button) => { | |
button.addEventListener('click', (e) => { | |
const buttonTitle = e.currentTarget.innerHTML; | |
// send event to GA4 | |
gtag('event', 'solo_btn_click', { | |
'event_category': 'click', | |
'cta_category': 'button', | |
'page_title': pageTitle, | |
'page_location': pageUrl, | |
'btn_title': buttonTitle, | |
'btn_id': e.currentTarget.id, | |
'btn_type': e.currentTarget.getAttribute('data-type'), | |
'btn_link_url': e.currentTarget.href, | |
'link_url': e.currentTarget.href | |
}); | |
}); | |
}); | |
} | |
// FOOTER CTA BOXES ####### | |
const footerCTAbox = document.querySelectorAll('a.footer-cta-box'); | |
if([...footerCTAbox].length > 0){ | |
footerCTAbox.forEach((footerCTAbox) => { | |
footerCTAbox.addEventListener('click', (e) => { | |
const ctaTitle = e.currentTarget.querySelector('h5').innerHTML; | |
// send event to GA4 | |
gtag('event', 'solo_CTA_click', { | |
'event_category': 'click', | |
'cta_category': 'Footer CTA', | |
'page_title': pageTitle, | |
'page_location': pageUrl, | |
'cta_title': ctaTitle | |
}); | |
}); | |
}); | |
} | |
// INLINE CTAS, ON TOPIC PAGES ####### | |
const secondaryCTA = document.querySelector('.secondary-cta'); | |
if(secondaryCTA){ | |
var ctaTitle = secondaryCTA.querySelector('span').innerHTML; | |
// strip out the svg arrow elements that is probably in the string | |
ctaTitle = ctaTitle.replace(/<svg.*<\/svg>/g, ''); | |
//console.log(ctaTitle); | |
secondaryCTA.addEventListener('click', () => { | |
// send event to GA4 | |
gtag('event', 'solo_CTA_click', { | |
'event_category': 'click', | |
'cta_category': 'Inline CTA', | |
'page_title': pageTitle, | |
'page_location': pageUrl, | |
'cta_title': ctaTitle | |
}); | |
}); | |
} | |
// Video Plays | |
// Set up YouTube frame(s) to enable postmessages | |
const youTubeFrames = document.querySelectorAll('iframe[src*="youtu"]'); | |
if([...youTubeFrames].length > 0){ | |
youTubeFrames.forEach(frame => { | |
// Ensure the youtube frames have the jsapi loaded | |
if(!frame.src.includes('enablejsapi=1')){ | |
let url = new URL(frame.src); | |
let params = new URLSearchParams(url.search); | |
params.append('enablejsapi', 1); | |
url.search = params.toString(); | |
frame.src = url.toString(); | |
} | |
// Inform the embedded YouTube player that we're listening for postmessages | |
frame.contentWindow.postMessage('{"event":"listening","id":1,"channel":"widget"}', '*'); | |
}); | |
} | |
// Listen for postmessages from video frames | |
window.addEventListener('message', message => { | |
if(message.origin.includes("vidyard")){ | |
const messageData = JSON.parse(message.data); | |
let videoData = { | |
'event_category': 'video', | |
'page_title': document.title, | |
'page_location': window.location.href, | |
'video_url': 'https://play.vidyard.com/' + messageData.uuid + '/', | |
}; | |
if(messageData.event === 'playerComplete'){ | |
videoData.video_action = 'completed'; | |
videoData.current_time = messageData.currentTime; | |
gtag('event', 'solo_video_play', videoData); // Send to GA4 | |
} | |
if(messageData.event === 'play'){ | |
if(messageData.status.currentTime === 0){ | |
videoData.video_action = 'play'; | |
videoData.current_time = 0; | |
} else { | |
videoData.video_action = 'resume'; | |
videoData.current_time = messageData.currentTime; | |
} | |
gtag('event', 'solo_video_play', videoData); // Send to GA4 | |
} | |
if(messageData.event === 'pause'){ | |
videoData.video_action = 'pause'; | |
videoData.current_time = messageData.status.currentTime; | |
gtag('event', 'solo_video_play', videoData); // Send to GA4 | |
} | |
} | |
// YouTube | |
if(message.origin.includes("youtu")){ | |
const messageData = JSON.parse(message.data); | |
let videoData = { | |
'event_category': 'video', | |
'page_title': document.title, | |
'page_location': window.location.href, | |
}; | |
if(messageData.event === 'infoDelivery'){ | |
if('playerState' in messageData.info){ | |
// Ended | |
if(messageData.info.playerState === 0){ | |
videoData.video_action = 'completed'; | |
videoData.current_time = messageData.info.currentTime; | |
videoData.video_url = messageData.info.videoUrl; | |
gtag('event', 'solo_video_play', videoData); // Send to GA4 | |
} | |
// Playing (play or resume) | |
if(messageData.info.playerState === 1){ | |
if(messageData.info.currentTime < 0.2){ | |
videoData.video_action = 'play'; | |
videoData.current_time = 0; | |
} else { | |
videoData.video_action = 'resume'; | |
videoData.current_time = messageData.info.currentTime; | |
} | |
videoData.video_url = messageData.info.videoUrl; | |
gtag('event', 'solo_video_play', videoData); // Send to GA4 | |
} | |
// Paused | |
if(messageData.info.playerState === 2){ | |
videoData.video_url = messageData.info.videoUrl; | |
videoData.current_time = 0; | |
gtag('event', 'solo_video_play', videoData); // Send to GA4 | |
} | |
} | |
} | |
} | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment