feat(analytics): migrate to GA4
This commit is contained in:
@@ -36,7 +36,7 @@
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-dropdown-select": "^4.4.2",
|
||||
"react-ga": "^3.1.2",
|
||||
"react-ga4": "^2.0.0",
|
||||
"react-hotkeys-hook": "^3.2.1",
|
||||
"react-use": "^17.4.0",
|
||||
"recoil": "^0.7.6",
|
||||
@@ -49,7 +49,6 @@
|
||||
"@types/node": "^18.11.18",
|
||||
"@types/react": "^18.0.27",
|
||||
"@types/react-dom": "^18.0.10",
|
||||
"@types/react-virtualized": "^9.21.10",
|
||||
"@types/tinycolor2": "^1.4.3",
|
||||
"@vitejs/plugin-react": "^3.1.0",
|
||||
"typescript": "^4.9.5",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Medal } from "phosphor-react";
|
||||
import ReactGA from "react-ga";
|
||||
import ReactGA from "react-ga4";
|
||||
|
||||
import "./Banner.css";
|
||||
|
||||
|
||||
@@ -4,8 +4,8 @@ import { useHotkeys } from "react-hotkeys-hook";
|
||||
import { motion, AnimatePresence, Variants } from "framer-motion";
|
||||
import { Svg2Png } from "svg2png-converter";
|
||||
import { saveAs } from "file-saver";
|
||||
import { Copy, X, CheckCircle, Download } from "phosphor-react";
|
||||
import ReactGA from "react-ga";
|
||||
import { Copy, CheckCircle, Download } from "phosphor-react";
|
||||
import ReactGA from "react-ga4";
|
||||
|
||||
import {
|
||||
iconWeightAtom,
|
||||
@@ -16,7 +16,7 @@ import {
|
||||
import { isDarkThemeSelector } from "@/state/selectors";
|
||||
import Tabs, { Tab } from "@/components/Tabs";
|
||||
import useTransientState from "@/hooks/useTransientState";
|
||||
import { IconEntry, SnippetType } from "@/lib";
|
||||
import { SnippetType } from "@/lib";
|
||||
import { getCodeSnippets, supportsWeight } from "@/utils";
|
||||
|
||||
import TagCloud from "./TagCloud";
|
||||
|
||||
@@ -5,7 +5,7 @@ import { motion } from "framer-motion";
|
||||
import { Svg2Png } from "svg2png-converter";
|
||||
import { saveAs } from "file-saver";
|
||||
import { Copy, X, CheckCircle, Download } from "phosphor-react";
|
||||
import ReactGA from "react-ga";
|
||||
import ReactGA from "react-ga4";
|
||||
|
||||
import {
|
||||
iconWeightAtom,
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
a.nav-link {
|
||||
text-decoration: none;
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
color: black;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { OutboundLink } from "react-ga";
|
||||
import { ArrowElbowDownRight } from "phosphor-react";
|
||||
|
||||
import { iconCount } from "@/lib/icons";
|
||||
import OutboundLink from "@/components/OutboundLink";
|
||||
|
||||
import "./Links.css";
|
||||
|
||||
@@ -14,7 +14,7 @@ const Links = (_: LinksProps) => {
|
||||
<ArrowElbowDownRight size={24} />
|
||||
<OutboundLink
|
||||
className="nav-link"
|
||||
to="https://phosphoricons.com/assets/phosphor-icons.zip"
|
||||
href="https://phosphoricons.com/assets/phosphor-icons.zip"
|
||||
eventLabel="Download all"
|
||||
download
|
||||
type="application/zip"
|
||||
@@ -22,31 +22,30 @@ const Links = (_: LinksProps) => {
|
||||
Download all ({iconCount})
|
||||
</OutboundLink>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<ArrowElbowDownRight size={24} />
|
||||
<span>
|
||||
<OutboundLink
|
||||
className="nav-link"
|
||||
to="https://www.figma.com/community/file/903830135544202908/Phosphor-Icons"
|
||||
href="https://www.figma.com/community/file/903830135544202908/Phosphor-Icons"
|
||||
eventLabel="Figma library"
|
||||
>
|
||||
Figma library
|
||||
</OutboundLink>
|
||||
{" / "}
|
||||
<OutboundLink
|
||||
className="nav-link"
|
||||
to="https://www.figma.com/community/plugin/898620911119764089/Phosphor-Icons"
|
||||
href="https://www.figma.com/community/plugin/898620911119764089/Phosphor-Icons"
|
||||
eventLabel="Figma plugin"
|
||||
>
|
||||
plugin
|
||||
</OutboundLink>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<ArrowElbowDownRight size={24} />
|
||||
<OutboundLink
|
||||
className="nav-link"
|
||||
to="https://phosphoricons.com/assets/phosphor-icons.sketchplugin.zip"
|
||||
href="https://phosphoricons.com/assets/phosphor-icons.sketchplugin.zip"
|
||||
eventLabel="Download sketch plugin"
|
||||
download
|
||||
type="application/zip"
|
||||
@@ -54,48 +53,40 @@ const Links = (_: LinksProps) => {
|
||||
Sketch plugin
|
||||
</OutboundLink>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<ArrowElbowDownRight size={24} />
|
||||
<span>
|
||||
<a className="nav-link" href="https://paypal.me/minoraxis">
|
||||
<OutboundLink href="https://paypal.me/minoraxis" eventLabel="Donate">
|
||||
Donate on PayPal
|
||||
</a>
|
||||
</OutboundLink>
|
||||
{" / "}
|
||||
<a className="nav-link" href="https://patreon.com/phosphoricons">
|
||||
<OutboundLink
|
||||
href="https://patreon.com/phosphoricons"
|
||||
eventLabel="Patreon"
|
||||
>
|
||||
Patreon
|
||||
</a>
|
||||
</OutboundLink>
|
||||
</span>
|
||||
</div>
|
||||
{/* <div>
|
||||
<ArrowElbowDownRight size={24} />
|
||||
<a className="nav-link" href="https://paypal.me/minoraxis">
|
||||
Donate on PayPal
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<ArrowElbowDownRight size={24} />
|
||||
<a className="nav-link" href="https://patreon.com/phosphoricons">
|
||||
Support us on Patreon
|
||||
</a>
|
||||
</div>
|
||||
*/}
|
||||
<div>
|
||||
<ArrowElbowDownRight size={24} />
|
||||
<a
|
||||
className="nav-link"
|
||||
<OutboundLink
|
||||
href="https://github.com/phosphor-icons/phosphor-home"
|
||||
eventLabel="GitHub"
|
||||
>
|
||||
GitHub
|
||||
</a>
|
||||
</OutboundLink>
|
||||
</div>
|
||||
<div>
|
||||
<ArrowElbowDownRight size={24} />
|
||||
<a
|
||||
className="nav-link"
|
||||
<OutboundLink
|
||||
href="https://github.com/phosphor-icons/phosphor-home/issues"
|
||||
eventLabel="Request"
|
||||
>
|
||||
Request an icon
|
||||
</a>
|
||||
</OutboundLink>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
64
src/components/OutboundLink/OutboundLink.tsx
Normal file
64
src/components/OutboundLink/OutboundLink.tsx
Normal 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;
|
||||
1
src/components/OutboundLink/index.ts
Normal file
1
src/components/OutboundLink/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export { default } from "./OutboundLink";
|
||||
@@ -9,7 +9,7 @@ import { useRecoilState } from "recoil";
|
||||
import { useDebounce } from "react-use";
|
||||
import { useHotkeys } from "react-hotkeys-hook";
|
||||
import { Command, MagnifyingGlass, X, HourglassHigh } from "phosphor-react";
|
||||
import ReactGA from "react-ga";
|
||||
import ReactGA from "react-ga4";
|
||||
|
||||
import { searchQueryAtom } from "@/state/atoms";
|
||||
import "./SearchInput.css";
|
||||
|
||||
@@ -19,6 +19,7 @@ const Tabs = ({ tabs }: TabsProps) => {
|
||||
<div className="tabs-header">
|
||||
{tabs.map((tab, i) => (
|
||||
<button
|
||||
key={i}
|
||||
className={`tab ${activeIndex === i ? "active" : ""}`}
|
||||
onClick={() => setActiveIndex(i)}
|
||||
>
|
||||
|
||||
@@ -2,10 +2,10 @@ import { StrictMode } from "react";
|
||||
import { createRoot } from "react-dom/client";
|
||||
import { RecoilRoot } from "recoil";
|
||||
import App from "./components/App";
|
||||
import ReactGA from "react-ga";
|
||||
import ReactGA from "react-ga4";
|
||||
|
||||
ReactGA.initialize("UA-179205759-1", { titleCase: false });
|
||||
ReactGA.pageview(window.location.pathname);
|
||||
const GA_MEASUREMENT_ID = 'G-1C1REQCLFB'
|
||||
ReactGA.initialize(GA_MEASUREMENT_ID);
|
||||
|
||||
const container = document.getElementById("root");
|
||||
const root = createRoot(container!);
|
||||
|
||||
Reference in New Issue
Block a user