matomoKMPTracker
0.5.0indexedLightweight client tracker for Matomo, tracking pageviews, events, goals, search, content and e‑commerce; offline persisted queue with retries, heartbeat pings, custom dimensions, pluggable backends.
Lightweight client tracker for Matomo, tracking pageviews, events, goals, search, content and e‑commerce; offline persisted queue with retries, heartbeat pings, custom dimensions, pluggable backends.
A lightweight, Kotlin Multiplatform (KMP) client tracker for Matomo. It lets you track page views, events, goals, on‑site search, content interactions, and e‑commerce across Android, iOS, tvOS, watchOS, macOS, Desktop (JVM), JavaScript, and WASM from one shared Kotlin codebase.
siteIdAdd the dependency to your KMP project.
// build.gradle.kts (module)
dependencies {
implementation("io.github.frankois944:matomoKMPTracker:<latest-version>")
}
Replace <latest-version> with the latest version published on Maven Central .
The Apple platform requires sqlite to be linked to your application
Some additional configuration need to be done :
// {project}/build.gradle.kts
wasmJsMain.dependencies {
implementation(devNpm("copy-webpack-plugin", "9.1.0"))
}
// OR
jsMain.dependencies {
implementation(devNpm("copy-webpack-plugin", "9.1.0"))
}
// {project}/webpack.config.d/sqljs.js
config.resolve = {
fallback: {
fs: false,
path: false,
crypto: false,
}
};
const CopyWebpackPlugin = ();
config..(
({
: [
]
})
);
Create a Tracker and send a few page views. The tracker automatically batches and dispatches events in the background.
import io.github.frankois944.matomoKMPTracker.Tracker
suspend fun setupAndTrack() {
val tracker = Tracker.create(
url = "https://your.matomo.tld/matomo.php",
siteId = 1,
)
tracker.trackView(listOf(, ))
}
Android-specific creation (Context is mandatory on Android):
val tracker = Tracker.create(
url = "https://your.matomo.tld/matomo.php",
siteId = 1,
context = applicationContext,
)
tracker.startNewSession() // optional: begin a new visit
tracker.trackView(listOf("index1"))
tracker.trackView(listOf("Products", "Shoes", "Running"))
You can provide a full URL yourself if needed:
tracker.trackView(
view = listOf("Products", "Shoes"),
url = "https://my.app/products/shoes"
)
tracker.trackEventWithCategory(
category = "Video",
action = "Play",
name = "Trailer",
value = 1f,
)
tracker.trackGoal(goalId = 1, revenue = 42.0f)
tracker.trackSearch(query = "Test Unit")
tracker.trackSearch(query = "Headphones", category = "Electronics")
tracker.trackSearch(query = "Headphones", category = "Electronics", resultCount = 10)
// Set once, applies to subsequent events
tracker.trackCampaign(name = "spring_sale", keyword = "newsletter")
// Then track an action
tracker.trackView(listOf("Landing"))
// Impression
tracker.trackContentImpression(
name = "Homepage Banner",
piece = "banner.jpg",
target = "https://my.app/offers"
)
// Interaction
tracker.trackContentInteraction(
name = "Homepage Banner",
interaction = "click",
piece = "banner.jpg",
target = "https://my.app/offers"
)
import io.github.frankois944.matomoKMPTracker.OrderItem
val items = listOf(
OrderItem(
sku = "SKU-001",
name = "Running Shoes",
category = "Shoes",
price = ,
quantity = ,
),
OrderItem(
sku = ,
name = ,
category = ,
price = ,
quantity = ,
),
)
tracker.trackOrder(
id = ,
items = items,
revenue = ,
subTotal = ,
tax = ,
shippingCost = ,
discount = ,
)
Set global dimensions that will apply to all subsequent events:
tracker.setDimension(value = "premium", forIndex = 1)
tracker.setDimension(value = "ab-test-A", forIndex = 2)
Remove a dimension:
tracker.removeDimension(atIndex = 2)
Provide per‑event dimensions:
import io.github.frankois944.matomoKMPTracker.CustomDimension
tracker.trackView(
view = listOf("Catalog"),
dimensions = listOf(
CustomDimension(index = 3, value = "kiosk-mode"),
),
)
// Set a persistent user ID (e.g., username or hashed email)
tracker.setUserId("user_123")
// Later you can query it:
val currentUserId = tracker.userId()
// Start a new session (visit) — next event will mark a new visit in Matomo
tracker.startNewSession()
// Respect user privacy preferences
tracker.setOptOut(true) // events will be discarded while opted out
val isOptedOut = tracker.isOptedOut()
Heartbeat keeps a visit active by sending pings automatically.
// Enable or disable heartbeat; the preference is persisted
tracker.setIsHeartBeat(true)
val enabled = tracker.isHeartBeatEnabled()
When you do not pass a full URL to track calls, the library builds one for you. You can control the base host:
val tracker = Tracker.create(
url = "https://your.matomo.tld/matomo.php",
siteId = 1,
customActionHostUrl = "app.example", // results in http://app.example/<your-action>
)
Platform defaults for customActionHostUrl:
val tracker = Tracker.create(
url = "https://your.matomo.tld/matomo.php",
siteId = 1,
customUserAgent = "MyApp/1.0 (KMP)"
)
Provide your own HTTP dispatcher or queue implementation if you need custom transport or storage.
import io.github.frankois944.matomoKMPTracker.dispatcher.Dispatcher
import io.github.frankois944.matomoKMPTracker.queue.Queue
val tracker = Tracker.create(
url = "https://your.matomo.tld/matomo.php",
siteId = 1,
customDispatcher = myDispatcher, // implements Dispatcher
customQueue = myQueue // implements Queue
)
You can customize logging. The default logger is verbose for development.
import io.github.frankois944.matomoKMPTracker.MatomoTrackerLogger
import io.github.frankois944.matomoKMPTracker.DefaultMatomoTrackerLogger
import io.github.frankois944.matomoKMPTracker.LogLevel
val tracker = Tracker.create(url = "https://…/matomo.php", siteId = 1)
tracker.logger = DefaultMatomoTrackerLogger(minLevel = LogLevel.Info)
MIT 2025 © François Dabonot
Surfaced from shared tags and platforms — no rankings paid for.