Skip to content

Commit 2483c1d

Browse files
committed
add amplitude analytics
1 parent 31265a9 commit 2483c1d

6 files changed

Lines changed: 119 additions & 7 deletions

File tree

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
"version": "1.1.0",
44
"private": false,
55
"dependencies": {
6+
"@amplitude/analytics-browser": "^1.5.3",
67
"@testing-library/jest-dom": "^5.11.4",
78
"@testing-library/react": "^11.1.0",
89
"@testing-library/user-event": "^12.1.10",

src/App.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useState, useEffect, useContext, useRef } from 'react'
1+
import React, { useState, useEffect, useContext } from 'react'
22
import './App.css'
33
import ConfigurationContext from './configuration/ConfigurationContext'
44
import Footer from './components/Footer'
@@ -10,6 +10,7 @@ import ScrollCardsNavigator from './components/ScrollCardsNavigator'
1010
import AppContentLayout from './components/AppContentLayout'
1111
import 'react-contexify/dist/ReactContexify.css'
1212
import PreferencesContext from './preferences/PreferencesContext'
13+
import { initAnalytics } from './utils/Analytics'
1314

1415
function App() {
1516
const { marketingBannerConfig = {}, feedbackWidget } = useContext(ConfigurationContext)
@@ -18,6 +19,7 @@ function App() {
1819
const { dispatcher, ...state } = useContext(PreferencesContext)
1920

2021
useEffect(() => {
22+
initAnalytics()
2123
trackPageView('home')
2224
}, [])
2325

src/Constants.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ const APP = {
3434
dataSourcesLink: 'https://www.hackertab.dev/data-sources',
3535
changeLogLink: 'https://api.github.com/repos/medyo/hackertab.dev/releases',
3636
}
37+
export const ANALYTICS_ENDPOINT = 'https://api.hackertab.dev/analytics'
38+
export const ANALYTICS_SDK_KEY = '9662c93f91473ba6e96711b22e0a367d'
3739

3840
export const LOCAL_CONFIGURATION = {
3941
supportedTags: [], // Loaded remotly

src/preferences/AppReducer.js

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11

22
import { LS_PREFERENCES_KEY } from '../Constants';
33
import AppStorage from '../services/localStorage';
4-
4+
import {
5+
identifyUserLanguages,
6+
identifyUserCards,
7+
identifyListingMode,
8+
identifyUserTheme,
9+
} from '../utils/Analytics'
510

611
const AppReducer = (state, action) => {
712
let newState = { ...state }
@@ -10,13 +15,15 @@ const AppReducer = (state, action) => {
1015

1116
switch (action.type) {
1217
case 'setUserSelectedTags':
18+
identifyUserLanguages(value.map((tag) => tag.value))
1319
// check duplication.
1420
newState = {
1521
...newState,
1622
userSelectedTags: value,
1723
}
1824
break
1925
case 'setCards':
26+
identifyUserCards(value.map((card) => card.value))
2027
newState = { ...state, cards: value }
2128
break
2229
case 'setChangelogMeta':
@@ -27,6 +34,7 @@ const AppReducer = (state, action) => {
2734
if (!theme) {
2835
theme = state.theme === 'dark' ? 'light' : 'dark'
2936
}
37+
identifyUserTheme(theme)
3038
newState = { ...newState, theme }
3139
break
3240
case 'setOpenLinksNewTab':
@@ -36,6 +44,7 @@ const AppReducer = (state, action) => {
3644
}
3745
break
3846
case 'changelistingMode':
47+
identifyListingMode(value)
3948
newState = { ...newState, listingMode: value }
4049
break
4150
case 'bookmarkItem':

src/utils/Analytics.js

Lines changed: 52 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
11
import AppStorage from '../services/localStorage';
22
import { LS_ANALYTICS_ID_KEY } from '../Constants';
3+
import { init, track, Identify, identify } from '@amplitude/analytics-browser'
4+
import { ANALYTICS_SDK_KEY, ANALYTICS_ENDPOINT } from '../Constants'
35

6+
const initAnalytics = () => {
7+
init(ANALYTICS_SDK_KEY, getRandomUserId(), {
8+
disableCookies: true,
9+
serverUrl: ANALYTICS_ENDPOINT,
10+
})
11+
}
412
const trackPageScroll = (direction) => {
513
trackEvent('Pages', 'Scroll', direction)
614
}
@@ -41,6 +49,29 @@ const trackAddCard = (card) => {
4149
trackEvent('Card', 'Add', card)
4250
}
4351

52+
const identifyUserLanguages = (languages) => {
53+
const identity = new Identify()
54+
identity.set('Languages', languages)
55+
identify(identity)
56+
}
57+
58+
const identifyListingMode = (listingMode) => {
59+
const identity = new Identify()
60+
identity.set('ListingMode', listingMode)
61+
identify(identity)
62+
}
63+
const identifyUserCards = (cards) => {
64+
const identity = new Identify()
65+
identity.set('Sources', cards)
66+
identify(identity)
67+
}
68+
69+
const identifyUserTheme = (theme) => {
70+
const identity = new Identify()
71+
identity.set('Theme', theme)
72+
identify(identity)
73+
}
74+
4475
const trackRemoveCard = (card) => {
4576
trackEvent('Card', 'Remove', card)
4677
}
@@ -124,10 +155,9 @@ const trackEvent = (category, action, label) => {
124155
payload.append('el', label.capitalize())
125156
}
126157

127-
try {
128-
var manifestData = chrome.runtime.getManifest()
129-
payload.append('cd1', manifestData.version)
130-
} catch (e) {}
158+
payload.append('cd1', getAppVersion())
159+
160+
track(`${category.toLowerCase()}_${action.toLowerCase()}`)
131161

132162
if (process.env.NODE_ENV !== 'production') {
133163
console.log('Analytics debug payload', payload.toString())
@@ -137,28 +167,45 @@ const trackEvent = (category, action, label) => {
137167
navigator.sendBeacon('https://www.google-analytics.com/collect', payload.toString())
138168
}
139169

170+
const getAppVersion = () => {
171+
try {
172+
var manifestData = chrome.runtime.getManifest()
173+
return manifestData.version
174+
} catch (e) {
175+
return '0.0'
176+
}
177+
}
178+
/**
179+
* Generates a random user id
180+
*/
140181
const getRandomUserId = () => {
141182
let userId = AppStorage.getItem(LS_ANALYTICS_ID_KEY)
142183
if (!userId) {
143-
let newUserId = `${new Date().getTime()}${Math.random()}` // Random User Id
184+
let newUserId = `${new Date().getTime()}${Math.random()}`
144185
AppStorage.setItem(LS_ANALYTICS_ID_KEY, newUserId)
145186
userId = newUserId
146187
}
147188
return userId
148189
}
190+
149191
Object.assign(String.prototype, {
150192
capitalize() {
151193
return this.charAt(0).toUpperCase() + this.slice(1)
152194
},
153195
})
154196

155197
export {
198+
initAnalytics,
156199
trackPageView,
157200
trackThemeChange,
158201
trackOpenLinkFrom,
159202
trackAddLanguage,
160203
trackRemoveLanguage,
161204
trackAddCard,
205+
identifyUserLanguages,
206+
identifyUserCards,
207+
identifyListingMode,
208+
identifyUserTheme,
162209
trackRemoveCard,
163210
trackOpenLinksNewTab,
164211
trackBookmarkFrom,

yarn.lock

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,52 @@
22
# yarn lockfile v1
33

44

5+
"@amplitude/analytics-browser@^1.5.3":
6+
version "1.5.3"
7+
resolved "https://registry.yarnpkg.com/@amplitude/analytics-browser/-/analytics-browser-1.5.3.tgz#d9ff16c2a9d5a1c906f92754d0aef1bc019971ac"
8+
integrity sha512-/rZneKmxPqBFdIY+DBvqPCs2xZkq4TYz0ZEq5/7Ov6mL5Jxq4kmmd6p0l7o8kvlXwDXkYdnUVYQaMS93eBF3CQ==
9+
dependencies:
10+
"@amplitude/analytics-client-common" "^0.2.4"
11+
"@amplitude/analytics-core" "^0.9.4"
12+
"@amplitude/analytics-types" "^0.10.3"
13+
"@amplitude/ua-parser-js" "^0.7.31"
14+
tslib "^2.3.1"
15+
16+
"@amplitude/analytics-client-common@^0.2.4":
17+
version "0.2.4"
18+
resolved "https://registry.yarnpkg.com/@amplitude/analytics-client-common/-/analytics-client-common-0.2.4.tgz#6304ca9ea1dc142593685f6b33b41108035293b1"
19+
integrity sha512-MMeb5ZG57xKmmegnyrYNzkAukTTQlwY1AsXTTUPZb9+m+cVESU7Xidtto9W8/crf9p7TEcVX8qK8GNsB2xr/+A==
20+
dependencies:
21+
"@amplitude/analytics-connector" "^1.4.5"
22+
"@amplitude/analytics-core" "^0.9.4"
23+
"@amplitude/analytics-types" "^0.10.3"
24+
tslib "^2.3.1"
25+
26+
"@amplitude/analytics-connector@^1.4.5":
27+
version "1.4.5"
28+
resolved "https://registry.yarnpkg.com/@amplitude/analytics-connector/-/analytics-connector-1.4.5.tgz#07e9375101332bd8b6f15e39e70f31f287e87ad0"
29+
integrity sha512-ELAP6ivg+13uSk+TOirGZE/92M+tTbeiQ/i7eXgDO4Hiy00Abf/UxO/rp9WovtxCyeFYTILrujEYxPv5cRQmFw==
30+
dependencies:
31+
"@amplitude/ua-parser-js" "0.7.31"
32+
33+
"@amplitude/analytics-core@^0.9.4":
34+
version "0.9.4"
35+
resolved "https://registry.yarnpkg.com/@amplitude/analytics-core/-/analytics-core-0.9.4.tgz#b7f8e0a558291d8347cd7fbe5b19660b1421ceed"
36+
integrity sha512-DUtWTIm6b7LMCC5Cde6hSjrye0MV7oz9rNmU5JrwaVepLIfjhVFm8vPdrIlIxkzVhrnvMn/dP7CTCz9EFJozmA==
37+
dependencies:
38+
"@amplitude/analytics-types" "^0.10.3"
39+
tslib "^2.3.1"
40+
41+
"@amplitude/analytics-types@^0.10.3":
42+
version "0.10.3"
43+
resolved "https://registry.yarnpkg.com/@amplitude/analytics-types/-/analytics-types-0.10.3.tgz#608094a2a9e93d74952200486f9c7fed25cbf851"
44+
integrity sha512-ZzMcLk4vM0ZLKfX8Vo1GqTKnyva3lH6EJzZ2pEjoAvoZKvkOM9TUpcn35qRiLyVTsMgiBi7G4SR+1T57gaQP9w==
45+
46+
"@amplitude/ua-parser-js@0.7.31", "@amplitude/ua-parser-js@^0.7.31":
47+
version "0.7.31"
48+
resolved "https://registry.yarnpkg.com/@amplitude/ua-parser-js/-/ua-parser-js-0.7.31.tgz#749bf7cb633cfcc7ff3c10805bad7c5f6fbdbc61"
49+
integrity sha512-+z8UGRaj13Pt5NDzOnkTBy49HE2CX64jeL0ArB86HAtilpnfkPB7oqkigN7Lf2LxscMg4QhFD7mmCfedh3rqTg==
50+
551
"@babel/code-frame@7.10.4", "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.5.5":
652
version "7.10.4"
753
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.10.4.tgz#168da1a36e90da68ae8d49c0f1b48c7c6249213a"
@@ -11531,6 +11577,11 @@ tslib@^1.10.0, tslib@^1.8.1, tslib@^1.9.0:
1153111577
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
1153211578
integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
1153311579

11580+
tslib@^2.3.1:
11581+
version "2.4.0"
11582+
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3"
11583+
integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==
11584+
1153411585
tsutils@^3.17.1:
1153511586
version "3.17.1"
1153611587
resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.17.1.tgz#ed719917f11ca0dee586272b2ac49e015a2dd759"

0 commit comments

Comments
 (0)