Skip to content

Commit e71de91

Browse files
authored
Merge pull request #340 from wpengine/analytics-events
Analytics events
2 parents 8ac37c6 + ea38cbe commit e71de91

File tree

10 files changed

+145
-41
lines changed

10 files changed

+145
-41
lines changed

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
"@heroicons/react": "^2.2.0",
2929
"@icons-pack/react-simple-icons": "^13.1.0",
3030
"@jsdevtools/rehype-url-inspector": "^2.0.2",
31+
"@next/third-parties": "^15.3.4",
3132
"@octokit/core": "^7.0.2",
3233
"@shikijs/transformers": "^3.6.0",
3334
"@sindresorhus/slugify": "^2.2.1",

pnpm-lock.yaml

Lines changed: 20 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/components/docs-breadcrumbs.jsx

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { ChevronRightIcon } from "@heroicons/react/24/outline";
22
import { useRouter } from "next/router";
33
import Link from "@/components/link";
4+
import { sendSelectItemEvent } from "@/lib/analytics.mjs";
45
import { normalizeHref } from "@/utils/strings";
56

67
export default function DocsBreadcrumbs({ routes }) {
@@ -59,6 +60,16 @@ export default function DocsBreadcrumbs({ routes }) {
5960
href={breadcrumb.route}
6061
noDefaultStyles
6162
aria-label={breadcrumb.title}
63+
onClick={() => {
64+
sendSelectItemEvent({
65+
list: { id: "docs_breadcrumbs", name: "Docs Breadcrumbs" },
66+
item: {
67+
item_id: breadcrumb.route,
68+
item_name: breadcrumb.title,
69+
item_category: "mdx_doc",
70+
},
71+
});
72+
}}
6273
>
6374
<span>{breadcrumb.title}</span>
6475
<span>

src/components/docs-nav.jsx

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { CloseButton } from "@headlessui/react";
22
import Link from "@/components/link";
3+
import { sendSelectItemEvent } from "@/lib/analytics.mjs";
34
import { normalizeHref, classNames } from "@/utils/strings";
45

56
export default function DocsNav({
@@ -42,6 +43,19 @@ function NavItem({ item, level, isMobileMenu, ...props }) {
4243
href={normalizeHref(item.route)}
4344
noDefaultStyles
4445
activeClassName="text-blue-500 active"
46+
onClick={() => {
47+
sendSelectItemEvent({
48+
list: {
49+
id: isMobileMenu ? "mobile_docs_nav" : "docs_nav",
50+
name: isMobileMenu ? "Mobile Docs Nav" : "Docs Nav",
51+
},
52+
item: {
53+
item_id: item.route,
54+
item_name: item.title,
55+
item_category: "mdx_doc",
56+
},
57+
});
58+
}}
4559
{...props}
4660
>
4761
{item.title}

src/components/primary-nav.jsx

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
import { Bars3Icon, XMarkIcon } from "@heroicons/react/24/outline";
88
import { forwardRef } from "react";
99
import Link from "@/components/link";
10+
import { sendSelectItemEvent } from "@/lib/analytics.mjs";
1011
import { classNames } from "@/utils/strings";
1112

1213
const navItemClass =
@@ -20,6 +21,16 @@ const CustomLink = forwardRef((props, reference) => {
2021
);
2122
});
2223

24+
const sendMainNavItemSelectEvent = (item) => {
25+
sendSelectItemEvent({
26+
list: {
27+
id: "main_nav",
28+
name: "Main Nav",
29+
},
30+
item,
31+
});
32+
};
33+
2334
export default function PrimaryMenu({ isMenuOpen, setIsMenuOpen, className }) {
2435
return (
2536
<nav className={classNames("flex items-center space-x-4", className)}>
@@ -30,6 +41,13 @@ export default function PrimaryMenu({ isMenuOpen, setIsMenuOpen, className }) {
3041
href="/docs/"
3142
noDefaultStyles
3243
activeClassName="text-purple-500"
44+
onClick={() =>
45+
sendMainNavItemSelectEvent({
46+
item_id: "/docs/",
47+
item_name: "Docs",
48+
item_category: "mdx_doc",
49+
})
50+
}
3351
>
3452
Docs
3553
</Link>
@@ -40,6 +58,13 @@ export default function PrimaryMenu({ isMenuOpen, setIsMenuOpen, className }) {
4058
href="/blog/"
4159
noDefaultStyles
4260
activeClassName="text-purple-500"
61+
onClick={() =>
62+
sendMainNavItemSelectEvent({
63+
item_id: "/blog/",
64+
item_name: "Blog",
65+
item_category: "post",
66+
})
67+
}
4368
>
4469
Blog
4570
</Link>
@@ -50,6 +75,13 @@ export default function PrimaryMenu({ isMenuOpen, setIsMenuOpen, className }) {
5075
href="/showcase/"
5176
noDefaultStyles
5277
activeClassName="text-purple-500"
78+
onClick={() =>
79+
sendMainNavItemSelectEvent({
80+
item_id: "/showcase/",
81+
item_name: "Showcase",
82+
item_category: "page",
83+
})
84+
}
5385
>
5486
Showcase
5587
</Link>
@@ -78,6 +110,13 @@ export default function PrimaryMenu({ isMenuOpen, setIsMenuOpen, className }) {
78110
noDefaultStyles
79111
href="/docs/"
80112
activeClassName="text-purple-500"
113+
onClick={() =>
114+
sendMainNavItemSelectEvent({
115+
item_id: "/docs/",
116+
item_name: "Docs",
117+
item_category: "mdx_doc",
118+
})
119+
}
81120
>
82121
Docs
83122
</CustomLink>
@@ -87,6 +126,13 @@ export default function PrimaryMenu({ isMenuOpen, setIsMenuOpen, className }) {
87126
noDefaultStyles
88127
href="/blog/"
89128
activeClassName="text-purple-500"
129+
onClick={() =>
130+
sendMainNavItemSelectEvent({
131+
item_id: "/blog/",
132+
item_name: "Blog",
133+
item_category: "post",
134+
})
135+
}
90136
>
91137
Blog
92138
</CustomLink>
@@ -96,6 +142,13 @@ export default function PrimaryMenu({ isMenuOpen, setIsMenuOpen, className }) {
96142
noDefaultStyles
97143
href="/showcase/"
98144
activeClassName="text-purple-500"
145+
onClick={() =>
146+
sendMainNavItemSelectEvent({
147+
item_id: "/showcase/",
148+
item_name: "Showcase",
149+
item_category: "page",
150+
})
151+
}
99152
>
100153
Showcase
101154
</CustomLink>

src/components/search-bar.jsx

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { useCombobox } from "downshift";
33
import debounce from "lodash.debounce";
44
import { useRouter } from "next/router";
55
import { useState, useEffect, useRef, useCallback } from "react";
6+
import { sendSearchEvent, sendSelectItemEvent } from "@/lib/analytics.mjs";
67

78
export default function SearchBar({ setIsSearchOpen }) {
89
const [items, setItems] = useState([]);
@@ -85,6 +86,8 @@ export default function SearchBar({ setIsSearchOpen }) {
8586
} catch (error) {
8687
console.error("Error fetching search results:", error);
8788
setItems([]);
89+
} finally {
90+
sendSearchEvent(value);
8891
}
8992
}, 500),
9093
).current;
@@ -203,11 +206,33 @@ export default function SearchBar({ setIsSearchOpen }) {
203206
index,
204207
onClick: () => {
205208
closeModal();
209+
sendSelectItemEvent({
210+
list: {
211+
id: "search_results",
212+
name: "Search Results",
213+
},
214+
item: {
215+
item_id: item.path,
216+
item_name: item.title,
217+
item_category: item.type,
218+
},
219+
});
206220
router.push(item.path);
207221
},
208222
onKeyDown: (event) => {
209223
if (event.key === "Enter") {
210224
closeModal();
225+
sendSelectItemEvent({
226+
list: {
227+
id: "search_results",
228+
name: "Search Results",
229+
},
230+
item: {
231+
item_id: item.path,
232+
item_name: item.title,
233+
item_category: item.type,
234+
},
235+
});
211236
router.push(item.path);
212237
}
213238
},

src/lib/analytics.mjs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import { sendGAEvent } from "@next/third-parties/google";
2+
3+
export function sendSearchEvent(term) {
4+
sendGAEvent("event", "search", {
5+
search_term: term,
6+
});
7+
}
8+
9+
export function sendSelectItemEvent({ list: { name, id }, item }) {
10+
sendGAEvent("event", "select_item", {
11+
item_list_id: id,
12+
item_list_name: name,
13+
item: [item],
14+
});
15+
}

src/lib/gtag.js

Lines changed: 0 additions & 10 deletions
This file was deleted.

src/pages/_app.jsx

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,25 @@
1+
/* eslint-disable n/prefer-global/process */
2+
/* eslint-disable no-restricted-globals */
13
import { WordPressBlocksProvider } from "@faustwp/blocks";
24
import { FaustProvider } from "@faustwp/core";
5+
import { GoogleAnalytics } from "@next/third-parties/google";
36
import { useRouter } from "next/router";
4-
import { useEffect } from "react";
57
import DocsLayout from "@/components/docs-layout";
68
import Layout from "@/components/layout";
7-
import { logPageview } from "@/lib/gtag.js";
89
import blocks from "@/wp-blocks";
910
import "../../faust.config";
1011
import "./global.css";
1112
import "@faustwp/core/dist/css/toolbar.css";
1213

14+
const GA_TRACKING_ID = process.env.NEXT_PUBLIC_GA_TRACKING_ID;
15+
1316
export default function MyApp({ Component, pageProps }) {
1417
const router = useRouter();
1518
const isDocsRoute = router.pathname.startsWith("/docs");
1619

17-
// Record a Google Analytics pageview on route change
18-
useEffect(() => {
19-
const handleRouteChange = (url) => logPageview(url);
20-
21-
router.events.on("routeChangeComplete", handleRouteChange);
22-
return () => {
23-
router.events.off("routeChangeComplete", handleRouteChange);
24-
};
25-
}, [router.events]);
26-
2720
return (
2821
<FaustProvider pageProps={pageProps}>
22+
<GoogleAnalytics gaId={GA_TRACKING_ID} />
2923
{/* eslint-disable-next-line unicorn/no-null */}
3024
<WordPressBlocksProvider config={{ blocks, theme: null }}>
3125
<Layout>

src/pages/_document.jsx

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,13 @@
11
import { env } from "node:process";
22
import { URL } from "node:url";
33
import { Html, Head, Main, NextScript } from "next/document";
4-
import { GA_TRACKING_ID } from "@/lib/gtag";
54

65
const SITE_URL = env.NEXT_PUBLIC_SITE_URL;
76

87
export default function Document() {
98
return (
109
<Html lang="en">
1110
<Head>
12-
{/* Global Site Tag (gtag.js) - Google Analytics */}
13-
<script
14-
async
15-
src={`https://www.googletagmanager.com/gtag/js?id=${GA_TRACKING_ID}`}
16-
/>
17-
<script
18-
// eslint-disable-next-line react/no-danger
19-
dangerouslySetInnerHTML={{
20-
__html: `
21-
window.dataLayer = window.dataLayer || [];
22-
function gtag(){dataLayer.push(arguments);}
23-
gtag('js', new Date());
24-
gtag('config', '${GA_TRACKING_ID}', {
25-
page_path: window.location.pathname,
26-
});
27-
`,
28-
}}
29-
/>
3011
<link href="/images/favicon-32x32.png" rel="icon" sizes="32x32" />
3112
<link href="/images/favicon-192x192.png" rel="icon" sizes="192x192" />
3213
<link

0 commit comments

Comments
 (0)