feat(analytics): migrate to GA4

This commit is contained in:
rektdeckard
2023-02-05 17:57:52 -07:00
parent 5e7f85ffdc
commit 3756374140
11 changed files with 99 additions and 42 deletions

View File

@@ -36,7 +36,7 @@
"react": "^18.2.0", "react": "^18.2.0",
"react-dom": "^18.2.0", "react-dom": "^18.2.0",
"react-dropdown-select": "^4.4.2", "react-dropdown-select": "^4.4.2",
"react-ga": "^3.1.2", "react-ga4": "^2.0.0",
"react-hotkeys-hook": "^3.2.1", "react-hotkeys-hook": "^3.2.1",
"react-use": "^17.4.0", "react-use": "^17.4.0",
"recoil": "^0.7.6", "recoil": "^0.7.6",
@@ -49,7 +49,6 @@
"@types/node": "^18.11.18", "@types/node": "^18.11.18",
"@types/react": "^18.0.27", "@types/react": "^18.0.27",
"@types/react-dom": "^18.0.10", "@types/react-dom": "^18.0.10",
"@types/react-virtualized": "^9.21.10",
"@types/tinycolor2": "^1.4.3", "@types/tinycolor2": "^1.4.3",
"@vitejs/plugin-react": "^3.1.0", "@vitejs/plugin-react": "^3.1.0",
"typescript": "^4.9.5", "typescript": "^4.9.5",

View File

@@ -1,5 +1,5 @@
import { Medal } from "phosphor-react"; import { Medal } from "phosphor-react";
import ReactGA from "react-ga"; import ReactGA from "react-ga4";
import "./Banner.css"; import "./Banner.css";

View File

@@ -4,8 +4,8 @@ import { useHotkeys } from "react-hotkeys-hook";
import { motion, AnimatePresence, Variants } from "framer-motion"; import { motion, AnimatePresence, Variants } from "framer-motion";
import { Svg2Png } from "svg2png-converter"; import { Svg2Png } from "svg2png-converter";
import { saveAs } from "file-saver"; import { saveAs } from "file-saver";
import { Copy, X, CheckCircle, Download } from "phosphor-react"; import { Copy, CheckCircle, Download } from "phosphor-react";
import ReactGA from "react-ga"; import ReactGA from "react-ga4";
import { import {
iconWeightAtom, iconWeightAtom,
@@ -16,7 +16,7 @@ import {
import { isDarkThemeSelector } from "@/state/selectors"; import { isDarkThemeSelector } from "@/state/selectors";
import Tabs, { Tab } from "@/components/Tabs"; import Tabs, { Tab } from "@/components/Tabs";
import useTransientState from "@/hooks/useTransientState"; import useTransientState from "@/hooks/useTransientState";
import { IconEntry, SnippetType } from "@/lib"; import { SnippetType } from "@/lib";
import { getCodeSnippets, supportsWeight } from "@/utils"; import { getCodeSnippets, supportsWeight } from "@/utils";
import TagCloud from "./TagCloud"; import TagCloud from "./TagCloud";

View File

@@ -5,7 +5,7 @@ import { motion } from "framer-motion";
import { Svg2Png } from "svg2png-converter"; import { Svg2Png } from "svg2png-converter";
import { saveAs } from "file-saver"; import { saveAs } from "file-saver";
import { Copy, X, CheckCircle, Download } from "phosphor-react"; import { Copy, X, CheckCircle, Download } from "phosphor-react";
import ReactGA from "react-ga"; import ReactGA from "react-ga4";
import { import {
iconWeightAtom, iconWeightAtom,

View File

@@ -23,6 +23,7 @@
a.nav-link { a.nav-link {
text-decoration: none; text-decoration: none;
position: relative; position: relative;
cursor: pointer;
color: black; color: black;
} }

View File

@@ -1,7 +1,7 @@
import { OutboundLink } from "react-ga";
import { ArrowElbowDownRight } from "phosphor-react"; import { ArrowElbowDownRight } from "phosphor-react";
import { iconCount } from "@/lib/icons"; import { iconCount } from "@/lib/icons";
import OutboundLink from "@/components/OutboundLink";
import "./Links.css"; import "./Links.css";
@@ -14,7 +14,7 @@ const Links = (_: LinksProps) => {
<ArrowElbowDownRight size={24} /> <ArrowElbowDownRight size={24} />
<OutboundLink <OutboundLink
className="nav-link" className="nav-link"
to="https://phosphoricons.com/assets/phosphor-icons.zip" href="https://phosphoricons.com/assets/phosphor-icons.zip"
eventLabel="Download all" eventLabel="Download all"
download download
type="application/zip" type="application/zip"
@@ -22,31 +22,30 @@ const Links = (_: LinksProps) => {
Download all ({iconCount}) Download all ({iconCount})
</OutboundLink> </OutboundLink>
</div> </div>
<div> <div>
<ArrowElbowDownRight size={24} /> <ArrowElbowDownRight size={24} />
<span> <span>
<OutboundLink <OutboundLink
className="nav-link" href="https://www.figma.com/community/file/903830135544202908/Phosphor-Icons"
to="https://www.figma.com/community/file/903830135544202908/Phosphor-Icons"
eventLabel="Figma library" eventLabel="Figma library"
> >
Figma library Figma library
</OutboundLink> </OutboundLink>
{" / "} {" / "}
<OutboundLink <OutboundLink
className="nav-link" href="https://www.figma.com/community/plugin/898620911119764089/Phosphor-Icons"
to="https://www.figma.com/community/plugin/898620911119764089/Phosphor-Icons"
eventLabel="Figma plugin" eventLabel="Figma plugin"
> >
plugin plugin
</OutboundLink> </OutboundLink>
</span> </span>
</div> </div>
<div> <div>
<ArrowElbowDownRight size={24} /> <ArrowElbowDownRight size={24} />
<OutboundLink <OutboundLink
className="nav-link" href="https://phosphoricons.com/assets/phosphor-icons.sketchplugin.zip"
to="https://phosphoricons.com/assets/phosphor-icons.sketchplugin.zip"
eventLabel="Download sketch plugin" eventLabel="Download sketch plugin"
download download
type="application/zip" type="application/zip"
@@ -54,48 +53,40 @@ const Links = (_: LinksProps) => {
Sketch plugin Sketch plugin
</OutboundLink> </OutboundLink>
</div> </div>
<div> <div>
<ArrowElbowDownRight size={24} /> <ArrowElbowDownRight size={24} />
<span> <span>
<a className="nav-link" href="https://paypal.me/minoraxis"> <OutboundLink href="https://paypal.me/minoraxis" eventLabel="Donate">
Donate on PayPal Donate on PayPal
</a> </OutboundLink>
{" / "} {" / "}
<a className="nav-link" href="https://patreon.com/phosphoricons"> <OutboundLink
href="https://patreon.com/phosphoricons"
eventLabel="Patreon"
>
Patreon Patreon
</a> </OutboundLink>
</span> </span>
</div> </div>
{/* <div>
<ArrowElbowDownRight size={24} />
<a className="nav-link" href="https://paypal.me/minoraxis">
Donate on PayPal
</a>
</div>
<div> <div>
<ArrowElbowDownRight size={24} /> <ArrowElbowDownRight size={24} />
<a className="nav-link" href="https://patreon.com/phosphoricons"> <OutboundLink
Support us on Patreon
</a>
</div>
*/}
<div>
<ArrowElbowDownRight size={24} />
<a
className="nav-link"
href="https://github.com/phosphor-icons/phosphor-home" href="https://github.com/phosphor-icons/phosphor-home"
eventLabel="GitHub"
> >
GitHub GitHub
</a> </OutboundLink>
</div> </div>
<div> <div>
<ArrowElbowDownRight size={24} /> <ArrowElbowDownRight size={24} />
<a <OutboundLink
className="nav-link"
href="https://github.com/phosphor-icons/phosphor-home/issues" href="https://github.com/phosphor-icons/phosphor-home/issues"
eventLabel="Request"
> >
Request an icon Request an icon
</a> </OutboundLink>
</div> </div>
</div> </div>
); );

View File

@@ -0,0 +1,64 @@
import {
DetailedHTMLProps,
AnchorHTMLAttributes,
useCallback,
MouseEventHandler,
} from "react";
import ReactGA from "react-ga4";
import { UaEventOptions } from "react-ga4/types/ga4";
interface OutboundLinkProps
extends DetailedHTMLProps<
AnchorHTMLAttributes<HTMLAnchorElement>,
HTMLAnchorElement
> {
eventLabel: string;
}
const NEWTAB = "_blank";
const MIDDLECLICK = 1;
const DEFAULT_META: UaEventOptions = {
category: "Outbound",
action: "Click",
};
const OutboundLink = ({
eventLabel,
target,
href,
...props
}: OutboundLinkProps) => {
const handleClick: MouseEventHandler<HTMLAnchorElement> = useCallback(
(event) => {
const eventMeta = { ...DEFAULT_META, label: eventLabel };
const sameTarget = target !== NEWTAB;
const normalClick = !(
event.ctrlKey ||
event.shiftKey ||
event.metaKey ||
event.button === MIDDLECLICK
);
if (!!href && sameTarget && normalClick) {
event.preventDefault();
ReactGA.event(eventMeta);
window.location.href = href;
} else {
ReactGA.event(eventMeta);
}
},
[href, eventLabel]
);
return (
<a
{...props}
href={href}
onClick={handleClick}
rel={target === NEWTAB ? "noopener noreferrer" : ""}
className="nav-link"
/>
);
};
export default OutboundLink;

View File

@@ -0,0 +1 @@
export { default } from "./OutboundLink";

View File

@@ -9,7 +9,7 @@ import { useRecoilState } from "recoil";
import { useDebounce } from "react-use"; import { useDebounce } from "react-use";
import { useHotkeys } from "react-hotkeys-hook"; import { useHotkeys } from "react-hotkeys-hook";
import { Command, MagnifyingGlass, X, HourglassHigh } from "phosphor-react"; import { Command, MagnifyingGlass, X, HourglassHigh } from "phosphor-react";
import ReactGA from "react-ga"; import ReactGA from "react-ga4";
import { searchQueryAtom } from "@/state/atoms"; import { searchQueryAtom } from "@/state/atoms";
import "./SearchInput.css"; import "./SearchInput.css";

View File

@@ -19,6 +19,7 @@ const Tabs = ({ tabs }: TabsProps) => {
<div className="tabs-header"> <div className="tabs-header">
{tabs.map((tab, i) => ( {tabs.map((tab, i) => (
<button <button
key={i}
className={`tab ${activeIndex === i ? "active" : ""}`} className={`tab ${activeIndex === i ? "active" : ""}`}
onClick={() => setActiveIndex(i)} onClick={() => setActiveIndex(i)}
> >

View File

@@ -2,10 +2,10 @@ import { StrictMode } from "react";
import { createRoot } from "react-dom/client"; import { createRoot } from "react-dom/client";
import { RecoilRoot } from "recoil"; import { RecoilRoot } from "recoil";
import App from "./components/App"; import App from "./components/App";
import ReactGA from "react-ga"; import ReactGA from "react-ga4";
ReactGA.initialize("UA-179205759-1", { titleCase: false }); const GA_MEASUREMENT_ID = 'G-1C1REQCLFB'
ReactGA.pageview(window.location.pathname); ReactGA.initialize(GA_MEASUREMENT_ID);
const container = document.getElementById("root"); const container = document.getElementById("root");
const root = createRoot(container!); const root = createRoot(container!);