Skip to content

Commit

Permalink
Added tutorial for consent mode
Browse files Browse the repository at this point in the history
  • Loading branch information
matt-landers committed May 22, 2023
1 parent ac9e951 commit f9042ec
Show file tree
Hide file tree
Showing 16 changed files with 509 additions and 0 deletions.
24 changes: 24 additions & 0 deletions tutorials/4-consent-mode/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# GA4 Tutorial Series - Consent Mode

This folder contains the code used in the
[Consent Mode tutorial video](https://youtu.be/MqAEbshMv84) on YouTube

## Run the current version of the website

You must install [Deno](https://deno.land) to run the website code.

Once you install Deno, run the local web server with the following command:

```
deno task start
```

Then, open [http://localhost](http://localhost) in your web browser.

# Join our community

💬 [Join](https://discord.gg/65mah7ZZsG) the official GA Discord server\
📝 [Sign up](https://groups.google.com/g/google-analytics-developer-newsletter)
for the Google Analytics Developer Newsletter\
📄 [Explore](https://developers.google.com/analytics/) GA4 developer
documentation
10 changes: 10 additions & 0 deletions tutorials/4-consent-mode/deno.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"tasks": {
"start": "deno run -A --watch=src/public/ src/index.ts"
},
"fmt": {
"files": {
"include": ["src/"]
}
}
}
5 changes: 5 additions & 0 deletions tutorials/4-consent-mode/src/deno.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"tasks": {
"start": "deno run -A --watch=public/ index.ts"
}
}
45 changes: 45 additions & 0 deletions tutorials/4-consent-mode/src/deno.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

55 changes: 55 additions & 0 deletions tutorials/4-consent-mode/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { configure, renderFile } from "https://deno.land/x/eta@v1.11.0/mod.ts";

const __dirname = new URL(".", import.meta.url).pathname;

const viewPath = [
`${__dirname}/public`,
`${__dirname}/public/partials`,
`${__dirname}/public/layouts`,
];

configure({ views: viewPath });

const server = Deno.listen({ port: 80 });

console.log("File server running on http://localhost:80/");

for await (const conn of server) {
handleHttp(conn).catch(console.error);
}

async function handleHttp(conn: Deno.Conn) {
const httpConn = Deno.serveHttp(conn);
for await (const requestEvent of httpConn) {
const url = new URL(requestEvent.request.url);
let filepath = decodeURIComponent(url.pathname);
if (filepath === "/") {
filepath = "index.eta";
} else if (filepath.toLocaleLowerCase().indexOf(".") <= 0) {
filepath = `${filepath}.eta`;
}

let file;
let response;
try {
console.log(filepath);
if (filepath.indexOf(".eta") > 0) {
response = new Response(await renderFile(filepath, {}), {
headers: { "content-type": "text/html" },
});
} else {
file = await Deno.open(__dirname + "public" + filepath, {
read: true,
});
const readableStream = file.readable;
response = new Response(readableStream);
}
} catch (e) {
console.error(e);
response = new Response("404 Not Found", { status: 404 });
return;
}

await requestEvent.respondWith(response);
}
}
32 changes: 32 additions & 0 deletions tutorials/4-consent-mode/src/public/about.eta
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<% layout("layout", { title: "About - GA Tutorials" }) %>

<%~ includeFile("nav") %>

<main class="container-lg pt-3 pb-5">
<h1 class="pt-4 pb-2">About the tutorial series</h1>
<a class="twitter-share-button" target="_blank"
href="https://twitter.com/intent/tweet?text=%23HelloAnalytics%20%23GA4TutorialSeries">
<span>Tweet</span></a>
<div class="pt-4 content-width">
<p>The Google Analytics 4 Tutorials series is a collection of videos created by the Google Analytics team to
help you learn how to use Google Analytics 4 and measure your website performance.</p>
<p>The videos in the series cover a wide range of topics, from setting up a Google Analytics 4 property to
using advanced features like ecommerce and user ID.</p>
<p>All the videos in the series can be found on the
<a href="https://www.youtube.com/channel/UCJ5UyIAa5nEGksjcdp43Ixw" target="_blank">Google
Analytics YouTube channel</a>, in the <a
href="https://youtube.com/playlist?list=PLI5YfMzCfRtZ4bHJJDl_IJejxMwZFiBwz" target="_blank">Google
Analytics 4
Tutorial playlist</a>. In addition to the
videos, the code for this website and other helpful resources are available in the <a
href="https://github.com/googleanalytics" target="_blank">Google Analytics GitHub repository</a>.
</p>
<p>For more information about Google Analytics, including new features and instructions,
see the Google Analytics <a href="https://support.google.com/analytics" target="_blank">help
center</a> and <a href="https://developers.google.com/analytics/devguides/collection/ga4"
target="_blank">developer site</a>.</p>
</div>
</main>

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

Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
106 changes: 106 additions & 0 deletions tutorials/4-consent-mode/src/public/index.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
.twitter-share-button,
.twitter-share-button:hover {
display: inline-block;
background-color: #1DA1F2;
border-radius: 9999px;
color: white;
text-decoration: none;
padding: 1px 12px;
font-size: 13px;
line-height: 26px;
font-family: "Helvetica Neue", Arial, sans-serif;
height: 28px;
font-weight: 500;
}

.twitter-share-button span {
margin-left: 3px;
}

.twitter-share-button i {
position: relative;
top: 2px;
display: inline-block;
width: 14px;
height: 14px;
background: transparent 0 0 no-repeat;
background-image: url(data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2072%2072%22%3E%3Cpath%20fill%3D%22none%22%20d%3D%22M0%200h72v72H0z%22%2F%3E%3Cpath%20class%3D%22icon%22%20fill%3D%22%23fff%22%20d%3D%22M68.812%2015.14c-2.348%201.04-4.87%201.744-7.52%202.06%202.704-1.62%204.78-4.186%205.757-7.243-2.53%201.5-5.33%202.592-8.314%203.176C56.35%2010.59%2052.948%209%2049.182%209c-7.23%200-13.092%205.86-13.092%2013.093%200%201.026.118%202.02.338%202.98C25.543%2024.527%2015.9%2019.318%209.44%2011.396c-1.125%201.936-1.77%204.184-1.77%206.58%200%204.543%202.312%208.552%205.824%2010.9-2.146-.07-4.165-.658-5.93-1.64-.002.056-.002.11-.002.163%200%206.345%204.513%2011.638%2010.504%2012.84-1.1.298-2.256.457-3.45.457-.845%200-1.666-.078-2.464-.23%201.667%205.2%206.5%208.985%2012.23%209.09-4.482%203.51-10.13%205.605-16.26%205.605-1.055%200-2.096-.06-3.122-.184%205.794%203.717%2012.676%205.882%2020.067%205.882%2024.083%200%2037.25-19.95%2037.25-37.25%200-.565-.013-1.133-.038-1.693%202.558-1.847%204.778-4.15%206.532-6.774z%22%2F%3E%3C%2Fsvg%3E)
}

main {
min-height: 75vh;
}

.divider {
height: 1rem;
background-color: rgba(0, 0, 0, .1);
border: solid rgba(0, 0, 0, .15);
border-width: 1px 0;
box-shadow: inset 0 .5em 1.5em rgba(0, 0, 0, .1), inset 0 .125em .5em rgba(0, 0, 0, .15);
}

.cookie-consent-banner {
display: none;
position: fixed;
bottom: 0;
left: 0;
right: 0;
background-color: #f8f9fa;
box-shadow: 0 -2px 10px rgba(0, 0, 0, 0.1);
color: black;
padding: 15px;
font-size: 14px;
text-align: center;
z-index: 1000;
}

.cookie-consent-button {
border: none;
padding: 8px 16px;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 14px;
margin: 4px 2px;
cursor: pointer;
border-radius: 4px;
}

.cookie-consent-button:hover {
box-shadow: 0 -2px 5px rgba(0, 0, 0, 0.2);
}

.cookie-consent-button:active {
opacity: .5;
}

.cookie-consent-button.btn-success {
background-color: #34a853;
color: white;
}

.cookie-consent-button.btn-grayscale {
background-color: #dfe1e5;
color: black;
}

.cookie-consent-button.btn-outline {
background-color: #e6f4ea;
color: #34a853;
}

.cookie-consent-options {
display: flex;
justify-content: center;
flex-wrap: wrap;
margin-bottom: 10px;
}

.cookie-consent-options label {
margin: 0 10px;
font-size: 14px;
}

.cookie-consent-options input {
margin-right: 5px;
}
25 changes: 25 additions & 0 deletions tutorials/4-consent-mode/src/public/index.eta
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<% layout("layout", { title: "Home | Google Analytics Tutorials" }) %>

<%~ includeFile("nav") %>

<main class="container-lg pt-3 pb-5">
<h1 class="pt-4 pb-2">Hello Analytics!</h1>
<a class="twitter-share-button" target="_blank"
href="https://twitter.com/intent/tweet?text=%23HelloAnalytics%20%23GA4TutorialSeries">
<span>Tweet</span></a>
<div class="pt-4 content-width">
<p>Welcome to the Google Analytics 4 Tutorial series!</p>
<p>In the series, we will build out this website to show you how to use Google Analytics 4 to measure your
website activity and performance. All of the code for the series can be found on the Google Analytics
GitHub account.</p>
<img src="/images/google-analytics.jpg" />
<p><span>Do you have any questions or topics that you'd like us to cover?</span> Please add your comments to
one of the videos in the series, and we will aim to cover it in a future video.</p>
<p>To learn more about this website and the series as a whole, check out <a href="/about">the About
page</a>.</p>
</div>
</main>

<%~ includeFile("footer") %>


55 changes: 55 additions & 0 deletions tutorials/4-consent-mode/src/public/layouts/layout.eta
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="shortcut icon" type="image/x-icon" href="images/favicon.png">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-Zenh87qX5JnK2Jl0vWa8Ck2rdkQ2Bzep5IDxbcnCeuOxjzrPF/et3URy9Bv1WTRi" crossorigin="anonymous">
<link rel="stylesheet" href="index.css">
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}

if(localStorage.getItem('consentMode') === null){
gtag('consent', 'default', {
'ad_storage': 'denied',
'analytics_storage': 'denied',
'personalization_storage': 'denied',
'functionality_storage': 'denied',
'security_storage': 'denied',
});
} else {
gtag('consent', 'default', JSON.parse(localStorage.getItem('consentMode')));
}
</script>
<!-- Google Tag Manager -->
<script>(function (w, d, s, l, i) {
w[l] = w[l] || []; w[l].push({
'gtm.start':
new Date().getTime(), event: 'gtm.js'
}); var f = d.getElementsByTagName(s)[0],
j = d.createElement(s), dl = l != 'dataLayer' ? '&l=' + l : ''; j.async = true; j.src =
'https://www.googletagmanager.com/gtm.js?id=' + i + dl; f.parentNode.insertBefore(j, f);
})(window, document, 'script', 'dataLayer', 'GTM-MHJNBK6');</script>
<!-- End Google Tag Manager -->
<title><%= it.title %></title>
</head>

<body>
<!-- Google Tag Manager (noscript) -->
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-MHJNBK6" height="0" width="0"
style="display:none;visibility:hidden"></iframe></noscript>
<!-- End Google Tag Manager (noscript) -->

<%~ it.body %>

<%~ includeFile("consent") %>

<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.2/dist/js/bootstrap.bundle.min.js"
integrity="sha384-OERcA2EqjJCMA+/3y+gxIOqMEjwtxJY7qPCqsdltbNJuaOe923+mo//f6V8Qbsw3"
crossorigin="anonymous"></script>
</body>
</html>
20 changes: 20 additions & 0 deletions tutorials/4-consent-mode/src/public/newsletter.eta
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<% layout("layout", { title: "Newsletter Signup - GA Tutorials" }) %>

<%~ includeFile("nav") %>

<main class="container-lg pt-3">
<h1>Signup for our Newsletter</h1>
<form id="newsletter-form" action="/thank-you">
<div class="form-group">
<label for="exampleInputEmail1">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
demo.</small>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
</main>

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

Loading

0 comments on commit f9042ec

Please sign in to comment.