Use Cases
Prefetching for feeds
Feed-style hosts often need to know whether an ad will fill before committing layout — see How Koah works for the prefetch model. Koah.instance.requestAd returns a one-shot KoahAdResult you can drive layout from:
import androidx.compose.runtime.*
import com.koahlabs.android.Koah
import com.koahlabs.android.KoahAdContext
import com.koahlabs.android.KoahAdResult
import com.koahlabs.android.KoahCard
@Composable
fun FeedRow(item: FeedItem) {
val context = remember(item) {
KoahAdContext.Feed(text = item.text, source = item.source)
}
var result by remember(item.id) { mutableStateOf<KoahAdResult?>(null) }
LaunchedEffect(item.id) {
result = Koah.instance.requestAd(adContext = context, cacheKey = item.id)
}
when (result) {
null -> ReservedSlot() // loading
is KoahAdResult.Filled -> KoahCard(adContext = context, cacheKey = item.id)
else -> Unit // no-fill or error: collapse
}
}
If you don't need explicit reserve/collapse layout — just "show an ad if one's available, otherwise nothing" — skip the requestAd step and call prefetchAd on first composition to warm the cache. KoahCard renders nothing on no-fill:
LaunchedEffect(item.id) {
Koah.instance.prefetchAd(adContext = context, cacheKey = item.id)
}
KoahCard(adContext = context, cacheKey = item.id)
| API | Use |
|---|---|
Koah.instance.requestAd(adContext, dimensions, cacheKey) | Ask for an ad and wait for the answer. Suspends, then returns a sealed KoahAdResult — Filled, NoFill, or Error (with a message) — each carrying fromCache. |
Koah.instance.prefetchAd(adContext, dimensions, cacheKey) | Warm the cache for a slot the user is about to see. Returns immediately with a Job; the network call runs in the background. No impression fires until the ad is actually rendered. |
Koah.instance.cancelPrefetchAd(cacheKey) | Cancel an in-flight prefetch. Cached results are untouched. |
KoahCard(adContext, cacheKey) | Render. Reads from the warmed cache on hit; renders nothing on no-fill. |
Slots
Tag an ad request with a slot to break down your dashboard reporting by where the ad renders — a feed card, an in-article unit, a chat sidebar. Register your slots in the dashboard first, then pass a registered name as slot on requestAd or prefetchAd:
val result = Koah.instance.requestAd(
adContext = KoahAdContext.Feed(text = item.text, source = item.source),
cacheKey = item.id,
slot = "in-article",
)
An unregistered slot resolves to no-fill (KoahAdResult.NoFill) and nothing
renders — register it in the dashboard before shipping. See
Slots for setup, naming rules, and reporting.