-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Tracker improved with more functions (#12)
* feat: tracker improved with more functions * BREAKING CHANGE: removing tracker cdn file replacement is pushed * fixes: coverage tests for tracker added
- Loading branch information
1 parent
450f970
commit c3585b7
Showing
12 changed files
with
195 additions
and
91 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,11 @@ | ||
import { Router } from 'express' | ||
import { sendAnalytics, trackAction } from './handlers'; | ||
import { Router } from "express"; | ||
import { sendAnalytics, trackAction, trackingScript } from "./handlers"; | ||
|
||
const router = Router(); | ||
|
||
const router = Router() | ||
router.post("/track", trackAction); | ||
router.get("/api/analytics", sendAnalytics); | ||
|
||
router.get("/scripts/tracker", trackingScript); | ||
|
||
|
||
router.post("/track", trackAction) | ||
router.get("/analytics", sendAnalytics) | ||
|
||
|
||
export default router; | ||
export default router; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
export const sendAnalyticsFn = (trackingUrl: string) => ` | ||
const sendAnalytics = async (eventType, additionalData = {}) => { | ||
try { | ||
const payload = { | ||
eventType, | ||
page: window.location.pathname, | ||
referrer: document.referrer, | ||
timestamp: new Date().toISOString(), | ||
sessionId, | ||
deviceInfo: getDeviceInfo(), | ||
url: window.location.origin, | ||
additionalData | ||
}; | ||
await fetch("${trackingUrl}", { | ||
method: "POST", | ||
headers: { "Content-Type": "application/json" }, | ||
body: JSON.stringify(payload), | ||
}); | ||
} catch (error) { | ||
console.error("Analytics tracking error:", error); | ||
} | ||
}; | ||
`; | ||
|
||
export const trackUserBehavior = ` | ||
// Ensure sendAnalytics is defined | ||
if (typeof sendAnalytics !== "function") { | ||
console.error("sendAnalytics is not defined."); | ||
return; | ||
} | ||
// Track clicks on the page | ||
document.addEventListener("click", (event) => { | ||
const target = event.target; | ||
const clickData = { | ||
tagName: target.tagName, | ||
id: target.id || null, | ||
classes: target.className || null, | ||
text: target.innerText ? target.innerText.slice(0, 50) : null, // Limit to 50 characters | ||
}; | ||
sendAnalytics("click", clickData); | ||
}); | ||
// Track scroll depth (debounced for performance) | ||
let maxScrollDepth = 0; | ||
let scrollTimeout; | ||
const handleScroll = () => { | ||
const scrollDepth = | ||
(window.scrollY + window.innerHeight) / document.body.scrollHeight; | ||
maxScrollDepth = Math.max(maxScrollDepth, scrollDepth); | ||
// Debounce updates to reduce frequency | ||
if (scrollTimeout) clearTimeout(scrollTimeout); | ||
scrollTimeout = setTimeout(() => { | ||
sendAnalytics("scroll", { maxScrollDepth }); | ||
}, 200); | ||
}; | ||
window.addEventListener("scroll", handleScroll); | ||
// Track form submissions | ||
document.addEventListener("submit", (event) => { | ||
const form = event.target; | ||
const formData = { | ||
action: form.action || null, | ||
method: form.method || null, | ||
}; | ||
sendAnalytics("form_submission", formData); | ||
}); | ||
// Track time spent on the page | ||
const pageStartTime = Date.now(); | ||
window.addEventListener("beforeunload", () => { | ||
const timeSpent = Math.round((Date.now() - pageStartTime) / 1000); | ||
sendAnalytics("time_on_page", { seconds: timeSpent, maxScrollDepth }); | ||
}); | ||
`; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
export const getSessionId = ` | ||
const getSessionId = () => { | ||
const sessionKey = "statstream_session"; | ||
let sessionId = localStorage.getItem(sessionKey); | ||
if (!sessionId) { | ||
sessionId = "ss-" + Math.random().toString(36).substr(2, 9); | ||
localStorage.setItem(sessionKey, sessionId); | ||
} | ||
return sessionId; | ||
}; | ||
`; | ||
|
||
export const getDeviceInfo = ` | ||
const getDeviceInfo = () => ({ | ||
userAgent: navigator.userAgent, | ||
platform: navigator.platform, | ||
language: navigator.language, | ||
}); | ||
`; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.