Skip to content

Commit

Permalink
Merge pull request #19 from googleanalytics/debugpanel
Browse files Browse the repository at this point in the history
Add a debug panel and Login page
  • Loading branch information
matt-landers committed Mar 12, 2024
2 parents 2ea638f + 585c30e commit f69a737
Show file tree
Hide file tree
Showing 6 changed files with 170 additions and 3 deletions.
8 changes: 7 additions & 1 deletion src/public/layouts/layout.eta
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@
} else {
gtag('consent', 'default', JSON.parse(localStorage.getItem('consentMode')));
}

if(localStorage.getItem('userId') != null) {
window.dataLayer.push({'user_id': localStorage.getItem('userId')});
}
</script>
<!-- Google Tag Manager -->
<script>(function (w, d, s, l, i) {
Expand All @@ -46,10 +50,12 @@

<%~ it.body %>

<%~ includeFile("debug") %>

<%~ includeFile("consent") %>

<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"
integrity="sha384-OERcA2EqjJCMA+/3y+gxIOqMEjwtxJY7qPCqsdltbNJuaOe923+mo//f6V8Qbsw3"
crossorigin="anonymous"></script>
</body>
</html>
</html>
83 changes: 83 additions & 0 deletions src/public/login.eta
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
<% layout("layout", { title: "Login - GA Tutorials" }) %>

<%~ includeFile("nav") %>

<main class="container-lg pt-3">
<h1>Simulate login to set User ID</h1>
<form id="login-form">
<div class="form-group">
<label for="user-id">GA4 User ID</label>
<input type="text" class="form-control" id="user" name="user-id" aria-describedby="userIdHelp"
placeholder="Enter User ID">
<small id="userIdHelp" class="form-text text-muted">This form simply
sets your User ID so tagging will include it in events. To log out, submit
the form without a value.</small>
</div>
<button type="submit" id="btn-login" class="btn btn-primary">Submit</button>
<button type="button" id="gen-id" class="btn btn-info">Generate ID</button>
<button type="button" id="btn-logout" class="btn btn-warning">Log out</button>
</form>
</main>

<script>

document.getElementById('btn-login').addEventListener('click', function() {
loginUserId(document.getElementById('user').value);
});

function loginUserId(userId) {
// Sets 'userId' in storage so layout.eta can set this in the dataLayer on
// each page.
localStorage.setItem('userId', userId);
}

document.getElementById('btn-logout').addEventListener('click', function() {
logout(document.getElementById('user'));
});

function logout(userIdField) {
localStorage.removeItem('userId');
userIdField.value = null;
}

document.getElementById('gen-id').addEventListener('click', function() {
generateUserId(document.getElementById('user'));
});

function generateUserId(userField) {
const prefixes = [
'doubloons',
'oceanographer',
'retrogressed',
'unmistakably',
'counterbalanced',
'wainscottings',
'servomechanism',
'expressionist',
'preciousness',
'fossilization',
'conglomerated',
'anthropomorphism',
'reappointment',
'transfigures',
'choreographer',
'sophisticated',
'calibrations',
'propitiating',
'effortlessly',
'prioritizing',
'rechargeable',
'thermostatic',
'acclimatization',
];
const randIndex = Math.floor(Math.random() * prefixes.length);
const randId = Math.floor(Math.random() * 1000 * 1000 * 1000 * 1000);
userField.value = prefixes[randIndex] + '-' + randId;
}

window.onload = () => document.getElementById('user').value = localStorage.getItem('userId');

</script>

<%~ includeFile("footer.eta") %>

2 changes: 1 addition & 1 deletion src/public/newsletter.eta
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<h1>Signup for our Newsletter</h1>
<form id="newsletter-form" action="/thank-you">
<div class="form-group">
<label for="exampleInputEmail1">Email address</label>
<label for="email">Email address</label>
<input type="email" class="form-control" id="email" name="email" aria-describedby="emailHelp"
placeholder="Enter email">
<small id="emailHelp" class="form-text text-muted">This form does not save your email. It is for the
Expand Down
75 changes: 75 additions & 0 deletions src/public/partials/debug.eta
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<div class="container-sm">
<button class="btn btn-info" type="button" data-bs-toggle="collapse" data-bs-target="#debug-panel" aria-expanded="true" aria-controls="debug-panel">Toggle debug panel</button>
<!-- Collapsible debug panel -->
<div class="collapse" id="debug-panel">
<button id="btn-fetch" class="btn btn-outline-primary">Fetch debug values</button>
<button id="btn-clear" class="btn btn-outline-warning">Clear client and session</button>
<br/>
<label for="tag-id">GA4 Tag ID</label>
<input type="text" class="form-control" id="tag-id" name="tag-id" disabled="true">
<label for="session-id">GA4 Session ID</label>
<input type="text" class="form-control" id="session-id" name="session-id" disabled="true">
<label for="client-id">GA4 Client ID</label>
<input type="text" class="form-control" id="client-id" name="client-id" disabled="true">
<label for="user-id">GA4 User ID</label>
<input type="text" class="form-control" id="user-id" name="user-id" disabled="true">
</div>
</div>

<script>
// Function for populating the debug panel values.
function setIds() {
// TODO: This may not be a reliable solution. From:
// https://stackoverflow.com/questions/76075126/given-gtm-installed-ga4-how-to-send-events-via-gtag-without-send-to
var gtagIds = Object.keys( window.google_tag_manager || [] ).filter( e => { return e.substring(0,2) == 'G-' } );
if (gtagIds) {
// Uses the first tag ID found.
const firstTagId = gtagIds[0];

// Gets each field that will be updated.
const tagIdField = document.getElementById('tag-id');
const sessionIdField = document.getElementById('session-id');
const clientIdField = document.getElementById('client-id');
const userIdField = document.getElementById('user-id');

Promise.all([
firstTagId,
localStorage.getItem('userId'),
// Gets values from gtag.
// See https://developers.google.com/tag-platform/gtagjs/reference#set_examples.
new Promise(cid => gtag('get', firstTagId, 'client_id', cid)),
new Promise(sid => gtag('get', firstTagId, 'session_id', sid)),
]).then(([tagId, userId, clientId, sessionId]) => {
// Updates value for each field.
tagIdField.value = tagId;
userIdField.value = userId;
clientIdField.value = clientId;
sessionIdField.value = sessionId;

// Logs info as an object.
console.log(JSON.stringify(
{
"user_id": userIdField.value,
"client_id": clientId,
"session_id": sessionId,
},
null,
' '));
});
}
}
document.getElementById('btn-fetch').addEventListener("click", setIds);

// Function for clearing the GA cookies.
function clearCookies() {
document.cookie.split('; ').map(c => c.split('=')[0]).forEach(
name => document.cookie = name + '=; expires=Thu, 01 Jan 1970 00:00:01 GMT;');
// Reloads the page.
location.reload();
}
document.getElementById('btn-clear').addEventListener("click", clearCookies);

// Populates the debug panel when shown.
document.getElementById('debug-panel').addEventListener('shown.bs.collapse', event =>
setIds());
</script>
2 changes: 1 addition & 1 deletion src/public/partials/footer.eta
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
<h5>Subscribe to our newsletter</h5>
<p>This is a demo and does not save your email.</p>
<div class="d-flex flex-column flex-sm-row w-100 gap-2">
<label for="newsletter1" class="visually-hidden">Email address</label>
<label for="email" class="visually-hidden">Email address</label>
<input id="email" name="email" type="text" class="form-control" placeholder="Email address">
<button class="btn btn-primary" type="submit">Subscribe</button>
</div>
Expand Down
3 changes: 3 additions & 0 deletions src/public/partials/nav.eta
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
<li class="nav-item">
<a class="nav-link" href="/profile">Profile</a>
</li>
<li class="nav-item">
<a class="nav-link" href="/login">Login</a>
</li>
</ul>
</div>
</div>
Expand Down

0 comments on commit f69a737

Please sign in to comment.