Skip to content

Commit 27f3e82

Browse files
committed
Add Umami analytics tracking for APK downloads
- Remove Plausible Analytics (canceled subscription) - Create Analytics utility for type-safe Umami event tracking - Update DownloadButton to track downloads with version metadata - Track 'apk-download' events with version and file properties
1 parent dc199d0 commit 27f3e82

3 files changed

Lines changed: 61 additions & 25 deletions

File tree

site/build.gradle.kts

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -36,20 +36,6 @@ kobweb {
3636
script {
3737
src = "/prism/prism.js"
3838
}
39-
script {
40-
async = true
41-
src = "https://plausible.io/js/pa-KV_Y-QH0U3Bxdqi_EJupK.js"
42-
}
43-
script {
44-
unsafe {
45-
raw(
46-
"""
47-
window.plausible=window.plausible||function(){(plausible.q=plausible.q||[]).push(arguments)},plausible.init=plausible.init||function(i){plausible.o=i||{}};
48-
plausible.init()
49-
""".trimIndent(),
50-
)
51-
}
52-
}
5339
script {
5440
defer = true
5541
src = "https://cloud.umami.is/script.js"

site/src/jsMain/kotlin/io/github/retar/portfolio/components/widgets/Button.kt

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import com.varabyte.kobweb.compose.ui.graphics.Colors
77
import com.varabyte.kobweb.compose.ui.modifiers.border
88
import com.varabyte.kobweb.compose.ui.modifiers.borderRadius
99
import com.varabyte.kobweb.compose.ui.modifiers.color
10+
import com.varabyte.kobweb.compose.ui.modifiers.onClick
1011
import com.varabyte.kobweb.compose.ui.modifiers.scale
1112
import com.varabyte.kobweb.compose.ui.modifiers.setVariable
1213
import com.varabyte.kobweb.compose.ui.modifiers.textDecorationLine
@@ -19,6 +20,7 @@ import com.varabyte.kobweb.silk.style.CssStyle
1920
import com.varabyte.kobweb.silk.style.selectors.hover
2021
import com.varabyte.kobweb.silk.style.toModifier
2122
import io.github.retar.portfolio.styles.sitePalette
23+
import io.github.retar.portfolio.utils.trackEvent
2224
import org.jetbrains.compose.web.css.LineStyle
2325
import org.jetbrains.compose.web.css.px
2426
import org.jetbrains.compose.web.dom.Text
@@ -47,18 +49,24 @@ fun DownloadButton(
4749
label: String,
4850
modifier: Modifier = Modifier,
4951
) {
50-
Link(
51-
path = url,
52-
modifier = Modifier.textDecorationLine(TextDecorationLine.None),
52+
Button(
53+
onClick = {
54+
// Track download event with Umami analytics
55+
val fileName = url.substringAfterLast("/")
56+
val version = fileName.removeSuffix(".apk")
57+
val eventData = js("{}")
58+
eventData["version"] = version
59+
eventData["file"] = fileName
60+
trackEvent("apk-download", eventData)
61+
62+
// Trigger download
63+
js("window.open")(url, "_self")
64+
},
65+
modifier = OutlineButtonStyle.toModifier()
66+
.then(modifier),
67+
size = ButtonSize.MD,
5368
) {
54-
Button(
55-
onClick = { },
56-
modifier = OutlineButtonStyle.toModifier()
57-
.then(modifier),
58-
size = ButtonSize.MD,
59-
) {
60-
Text(label)
61-
}
69+
Text(label)
6270
}
6371
}
6472

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package io.github.retar.portfolio.utils
2+
3+
/**
4+
* Umami analytics tracking utilities.
5+
*
6+
* Umami script is loaded via build.gradle.kts and provides a global `window.umami` object.
7+
*/
8+
external interface Umami {
9+
fun track(eventName: String)
10+
fun track(eventName: String, eventData: dynamic)
11+
}
12+
13+
/**
14+
* Access to the Umami analytics object.
15+
* Returns null if Umami is not loaded (e.g., ad blockers).
16+
*/
17+
val umami: Umami?
18+
get() = js("window.umami") as? Umami
19+
20+
/**
21+
* Track a custom event with Umami analytics.
22+
*
23+
* @param eventName The name of the event (max 50 characters)
24+
* @param eventData Optional data to attach to the event
25+
*/
26+
fun trackEvent(eventName: String, eventData: dynamic = null) {
27+
try {
28+
if (umami == null) {
29+
console.warn("Umami analytics not loaded. Event not tracked: $eventName")
30+
return
31+
}
32+
33+
if (eventData != null) {
34+
umami?.track(eventName, eventData)
35+
} else {
36+
umami?.track(eventName)
37+
}
38+
} catch (e: Throwable) {
39+
console.error("Failed to track event: $eventName", e)
40+
}
41+
}
42+

0 commit comments

Comments
 (0)