Skip to content

Instantly share code, notes, and snippets.

@grayayer
Created July 12, 2024 21:39
Show Gist options
  • Save grayayer/d26f27b82931a82691bb35f4e9116be7 to your computer and use it in GitHub Desktop.
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.
// 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