Skip to content

Commit

Permalink
Integrate Microsoft Clarity and Google Analytics [GA4]
Browse files Browse the repository at this point in the history
This commit integrates Microsoft Clarity and Google Analytics into our application.

- Added Microsoft Clarity and Google Analytics initialization in `utils/msclarity.client.ts` and `utils/gtags.client.ts` respectively.
- Utilized the tracking IDs in `root.tsx`.
- Updated Privacy Policy and Terms of Service to include disclosures for Microsoft Clarity and Google Analytics.
- Added Microsoft Clarity ID and Google Analytics Tracking ID to the .env.example file.
- Updated Privacy Policy and Terms of Service to include disclosures for Microsoft Clarity and Google Analytics on main imperfectgamers.org site
  • Loading branch information
cheesea3 committed May 16, 2024
1 parent e5e6682 commit ea664e7
Show file tree
Hide file tree
Showing 5 changed files with 193 additions and 6 deletions.
6 changes: 4 additions & 2 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,7 @@
STEAM_API_KEY=your_steam_api_key_here
AUTHORIZATION_URL=https://steamcommunity.com/openid/login
EMAIL_DOMAIN=steamcommunity.com
TEBEX_SECRET_KEY=your_tebex_secret_key_here
TEBEX_WEBSTORE_IDENTIFIER=your_tebex_webstore_identifier_here
TEBEX_SECRET_KEY=our_tebex_secret_key_here
TEBEX_WEBSTORE_IDENTIFIER=our_tebex_webstore_identifier_here
GA_TRACKING_ID=our_google_analytics_tracking_id_here
MS_CLARITY_ID=our_microsoft_clarity_id_here
52 changes: 49 additions & 3 deletions app/root.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// ~/root.tsx
import { type LinksFunction } from '@remix-run/node'
import { json, type LinksFunction } from '@remix-run/node'
import {
Link,
Links,
Expand All @@ -8,20 +8,43 @@ import {
Scripts,
ScrollRestoration,
isRouteErrorResponse,
useLoaderData,
useRouteError,
} from '@remix-run/react'
import type { ReactNode } from 'react'
import { useEffect, type ReactNode } from 'react'
import { ExternalScripts } from 'remix-utils/external-scripts'
import * as gtag from "~/utils/gtags.client";

import stylesheet from '~/tailwind.css?url'
import MsClarity from './utils/msclarity.client';

export const links: LinksFunction = () => [
{ rel: 'stylesheet', href: stylesheet },
]

// Load the GA tracking id from the .env
export const loader = async () => {
return json({
gaTrackingId: process.env.GA_TRACKING_ID,
msClarityId: process.env.MS_CLARITY_ID
});
};

// http://localhost:5173/store/


export function Layout({ children }: { children: React.ReactNode }) {
const { gaTrackingId, msClarityId } = useLoaderData<typeof loader>();

useEffect(() => {
if (gaTrackingId) {
gtag.pageview(window.location.pathname, gaTrackingId);
}
if(msClarityId){
MsClarity(msClarityId);
}
}, [gaTrackingId, msClarityId]);

return (
<html lang="en">
<head>
Expand All @@ -31,10 +54,33 @@ export function Layout({ children }: { children: React.ReactNode }) {
<Links />
</head>
<body className="background-svg relative flex flex-col bg-black px-4 text-white sm:px-8 md:px-12">
{process.env.NODE_ENV === "development" || !gaTrackingId ? null : (
<>
<script
async
src={`https://www.googletagmanager.com/gtag/js?id=${gaTrackingId}`}
/>
<script
async
id="gtag-init"
dangerouslySetInnerHTML={{
__html: `
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', '${gaTrackingId}', {
page_path: window.location.pathname,
});
`,
}}
/>
</>
)}
<main className="space-y-24 md:mx-72 md:space-y-12">{children}</main>
<ScrollRestoration />
<ExternalScripts />
<Scripts />
<ExternalScripts />
</body>
</html>
)
Expand Down
5 changes: 4 additions & 1 deletion app/routes/store.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,13 @@ export const links: LinksFunction = () => {
export let handle: ExternalScriptsHandle = {
scripts: [
{
src: '/1.0.0.js', // Updated to point to your local file
src: '/1.0.0.js', // Updated to point to Tebex
crossOrigin: 'anonymous',
preload: true,
},
{
src: "https://www.clarity.ms/tag/mcqzfowzo2",
}
],
}

Expand Down
53 changes: 53 additions & 0 deletions app/utils/gtags.client.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/**
*
* CREDITS TO https://github.com/remix-run/examples/blob/main/google-analytics/app/utils/gtags.client.ts
*
*/
declare global {
interface Window {
gtag: (
option: string,
gaTrackingId: string,
options: Record<string, unknown>,
) => void;
}
}

/**
* @example
* https://developers.google.com/analytics/devguides/collection/gtagjs/pages
*/
export const pageview = (url: string, trackingId: string) => {
if (!window.gtag) {
console.warn(
"window.gtag is not defined. This could mean your google analytics script has not loaded on the page yet.",
);
return;
}
window.gtag("config", trackingId, {
page_path: url,
});
};

/**
* @example
* https://developers.google.com/analytics/devguides/collection/gtagjs/events
*/
export const event = ({
action,
category,
label,
value,
}: Record<string, string>) => {
if (!window.gtag) {
console.warn(
"window.gtag is not defined. This could mean your google analytics script has not loaded on the page yet.",
);
return;
}
window.gtag("event", action, {
event_category: category,
event_label: label,
value: value,
});
};
83 changes: 83 additions & 0 deletions app/utils/msclarity.client.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import type { HtmlTagDescriptor, Plugin, ResolvedConfig } from "vite";

export interface MsClarityObjectOption {
/**
* The ID of the project Clarity provides to you.
*
* Can be found in the URL of your project.
*
* @example `k4vhy94oj3`
*/
id?: string;

/**
* The code to inject in the HTML.
*
* If provided, the `id` option will be ignored.
*
* If not provided, the script provided by Clarity will be used, with the `id` provided.
*/
script?: string;

/**
* Whether to inject the script in development mode.
*
* @default false
*/
enableInDevMode?: boolean;

/**
* Where to inject the script.
*
* @default "head-prepend"
*/
injectTo?: HtmlTagDescriptor["injectTo"];
}

export default function MsClarity(
idOrOptions: string | MsClarityObjectOption
): Plugin {
let config: ResolvedConfig;
return {
name: "ms-clarity",
enforce: "pre",
configResolved(resolvedConfig) {
config = resolvedConfig;
},
transformIndexHtml() {
const options: MsClarityObjectOption =
typeof idOrOptions === "string" ? { id: idOrOptions } : idOrOptions;

if (config.command === "serve" && !options.enableInDevMode) {
return;
}

if (!options.script && !options.id) {
throw new Error(
"[ms-clarity] No id provided. Please provide a id or a code to inject."
);
}

const script = options.script ?? toClarityScript(options.id!);

return [
{
tag: "script",
attrs: {
type: "text/javascript",
},
children: script,
injectTo: options.injectTo,
},
];
},
};
}

function toClarityScript(id: string) {
return `(function(c,l,a,r,i,t,y){
c[a]=c[a]||function(){(c[a].q=c[a].q||[]).push(arguments)};
t=l.createElement(r);t.async=1;t.src="https://www.clarity.ms/tag/"+i;
y=l.getElementsByTagName(r)[0];y.parentNode.insertBefore(t,y);
})(window, document, "clarity", "script", "${id}");`;
}

0 comments on commit ea664e7

Please sign in to comment.