feat(analytics): migrate to GA4
This commit is contained in:
@@ -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",
|
||||||
|
|||||||
@@ -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";
|
||||||
|
|
||||||
|
|||||||
@@ -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";
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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>
|
||||||
);
|
);
|
||||||
|
|||||||
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 { 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";
|
||||||
|
|||||||
@@ -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)}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -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!);
|
||||||
|
|||||||
Reference in New Issue
Block a user