AutographScope
Attaches properties to every event emitted from content — a screen-scoped context such as the article_id on an articles/{article_id} route.
composable("articles/{article_id}") { entry ->
val id = entry.arguments!!.getString("article_id")!!
AutographScope("article_id" to id) {
ArticleScreen() // every event below carries article_id
}
}The scope is installed by wrapping the ambient LocalTracker in a decorator that merges these properties into each event, so it applies uniformly to everything nested in content that reads the tracker — Modifier.trackClick / trackImpression, TrackScreenView / TrackedScreen, and plain LocalTracker.current.track(...) calls — with no per-call-site wiring.
Scopes nest and compose: an inner AutographScope adds to (and, on a key clash, overrides) the enclosing one. A property the call site passes explicitly always wins over the ambient scope, so the scope acts as a default that a specific event can still refine. Screen/section from TrackedScreen compose independently and are unaffected.
identify traits are intentionally not scoped: they describe the user, not the screen the event was fired on.
AutographScope overload taking a JsonObject, for scope values that aren't strings (numbers, booleans, nested objects) or that are already assembled as a JsonObject.