Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 81 additions & 22 deletions packages/static-site/src/pages/DataLayerGuide.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
import { FC } from "react";
import { Link } from "react-router-dom";
import { PagePaths } from "~/routes/config";
import { default as watchDataLayer } from "~/utils/watchDataLayerBookmarklet?raw";

export const bookmarklet = `javascript:(${watchDataLayer.toString()
// remove line breaks
.replace(/\n/g,"")
// remove comments
.replace(/\/\*.*?\*\//g, "")
// replace multiple spaces with a single space
.replace(/\s+/g, " ")})();`

const gtmCodes = {
universal: "GTM-KDWN8Z",
Expand All @@ -16,13 +25,13 @@ const GtmCodeExample: FC<{ gtmCode: string }> = ({ gtmCode }) => {
*/

const headScript = `
<!-- 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','${gtmCode}');</script>
<!-- End Google Tag Manager -->`;
<!-- 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','${gtmCode}');</script>
<!-- End Google Tag Manager -->`;
const bodyScript = `
<!-- Google Tag Manager (noscript) -->
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=${gtmCode}"
Expand Down Expand Up @@ -67,6 +76,11 @@ const DataLayerGuide = () => {
Adding the data layer to your site or application
</a>
</li>
<li>
<a href="#watchdatalayer">
Watching the data layer
</a>
</li>
</ul>

<a id="gtm"></a>
Expand Down Expand Up @@ -131,7 +145,7 @@ const DataLayerGuide = () => {
<p>
To implement Google Tag Manager, insert the appropriate snippets
found below within the body tag of your HTML as close to the top of
the page as possible. Further details can be found in the
the page as possible. Further details can be found in the{" "}
<a href="https://developers.google.com/tag-manager/quickstart">
Google Tag Manager Quickstart Guide
</a>
Expand All @@ -151,7 +165,7 @@ const DataLayerGuide = () => {

<p>
Some units have their own GTM IDs. When multiple GTM IDs need to be
used in a single site or application, follow the guidance on
used in a single site or application, follow the guidance on{" "}
<a href="https://developers.google.com/tag-manager/devguide#multiple-containers">
Multiple Containers on a Page
</a>
Expand Down Expand Up @@ -184,7 +198,7 @@ const DataLayerGuide = () => {
</p>

<p>
Follow the instructions for
Follow the instructions for{" "}
<a href="https://developers.google.com/tag-platform/tag-manager/web/datalayer">
creating the Data Layer
</a>{" "}
Expand All @@ -204,7 +218,11 @@ const DataLayerGuide = () => {
Add event listeners to your code to capture click and change events
related to your `data-ga` attributes and to push that event to the
data layer. As a help to get you started, the
`unity-bootstrap-theme` package&apos;s `dist/js/data-layer.js` file can
`unity-bootstrap-theme` package&apos;s{" "}
<a href="https://github.com/ASU/asu-unity-stack/blob/dev/packages/unity-bootstrap-theme/src/js/data-layer.js" target="_blank" rel="noreferrer">
src/js/data-layer.js
</a>{" "}
file can
serve as a starting point or as a reference for implementing your
own data layer push code.
</p>
Expand All @@ -214,29 +232,70 @@ const DataLayerGuide = () => {
behavior similar to the following code snippet if you implement the
Bootstrap header: <br />
</p>
<p>
Including the following script tag will automatically initialize the GA push events and header scroll
behavior and should be placed in the <strong>{`<head>`}</strong> tag of your HTML.
The script has event listeners to initialize on the window load event.
</p>
<pre>
<code>
{`
<script type="text/javascript" src="example/path/to/@asu/unity-bootstrap-theme/js/data-layer.js"></head> </script></head>
<script type="text/javascript" src="./@asu/unity-bootstrap-theme/js/global-header.js"></head> </script></head>
<script type="text/javascript" src="example/path/to/@asu/unity-bootstrap-theme/js/unity-bootstrap.umd.js"/>
`}
</code>
</pre>
<p>
Then, the following code should be placed towards the bottom of your
html doc or deferred. This initializes the data layer and the global
header classes
If for some reason your setup includes the script after the window load event has already occurred, you can call the initialization functions directly, by using the global variable <strong>{`unityBootstrap`}</strong>.
</p>
<pre>
{" "}
<code>
{`
<script></head>
window.initDataLayer();
window.initGlobalHeader();
</script></head>
<script>
/* Only use if the script did not automatically initialize with the window load event */
unityBootstrap.initDataLayer();
unityBootstrap.initGlobalHeader();
</script>
`}
</code>{" "}
</code>
</pre>

<a id="watchdatalayer"></a>
<h2>Watching the data layer</h2>
<p>
Drag this link to your bookmarks bar. When you are on a page with
data layer events, clicking the bookmarklet will execute a tiny
script which will output data layer events to the console.<br/><br/>
<a href={bookmarklet}>Watch DataLayer</a>
</p>
<h3>
Only Run Code You Trust
</h3>
<p>
As a user, always exercise caution when running code. Only click
or add bookmarklets if at least one of the following applies:
<ul>
<li>
The source is reputable.
</li>
<li>
You understand JavaScript and have reviewed the code
yourself.
</li>
<li>
A trusted individual who knows JavaScript has reviewed the
code for you.
</li>
</ul>


</p>
<h3>Bookmarklet Source code</h3>
<pre>
<code>
{`
${watchDataLayer.toString()}
`}
</code>
</pre>
</div>
</div>
Expand Down
14 changes: 12 additions & 2 deletions packages/static-site/src/utils/baseUrl.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,21 @@
import { PagePaths } from '../routes/config';

export const getBaseUrl = () => {

const pages = Object.values(PagePaths)
.filter((page) => page !== '/')
.map((page) => page.replace(/\//g, ''));

if (typeof window === 'undefined') return '/';

const pathname = window.location.pathname;

const segments = pathname.split('/').filter(Boolean);
return segments.length > 0 ? `/${segments[0]}` : '/';
const segments = pathname.split('/')
.filter(Boolean)
.filter((segment) => !pages.includes(segment))
.filter((segment) => segment.indexOf(".") === -1);

return `/${segments.join('/')}`;

};

Expand Down
38 changes: 38 additions & 0 deletions packages/static-site/src/utils/watchDataLayerBookmarklet.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
() => {
const w = window
, dl = w.dataLayer || []
/* used to provide styling in the console */
, styleKey = '\x1B[38;2;155;145;134;2m'
, styleValue = '\x1B[38;2;223;55;48;2m'
, styleDefault = '\x1B[0;3m'
, styleHeading = '\x1B[0;34;1m'
/* provide a global variable */
, tableFnName = 'showDataLayerTable';
/* display all watched events as console table */
w[tableFnName] = () => console.table(dl.slice().filter(i =>
typeof i.name !== 'undefined'));

if (typeof w.onbeforeunload !== 'function') {
/* initial click of bookmarklet */
dl.push = new Proxy(dl.push,{
apply: (target, thisArg, args) => {
console.log(`${styleHeading}dataLayer event\n${styleDefault}
{ ${(Object.entries(args[0]).map( ([k,v]) => (
`${styleKey}${k}${styleDefault}: ${styleValue}'${v}'${styleDefault}`
))).sort().join(', ')}${styleDefault} }`);
return Reflect.apply(target, thisArg, args);
}
});
alert(`DataLayer events will be displayed in console. Rerun bookmarklet or
call ${tableFnName}() from the console to display a table of all events.\n\n

A prompt will warn you before leaving the page, this is normal and will allow
you to inspect the dataLayer events, that would have reloaded the page.\n\n

Follow the prompt to reload or leave the page if you are done watching events.`);
w.onbeforeunload = (e) => '';
} else {
/* if already initialized, output recorded events */
w[tableFnName]();
}
}