Skip to content

Rewrite or serve map requests

Tiles, sprites, and fonts come from URLs in the style. MapRequestInterceptor rewrites those URLs or adds HTTP headers. MapResourceProvider supplies bytes for rewritten URLs it accepts.

Set either or both hooks in the runtime configuration block. They are fixed for the runtime’s lifetime and apply to its maps, snapshotters, and offline operations. Call DefaultMapRuntime.configure during application startup, before the first map, snapshotter, or offline storage:

App.kt
fun configureMapRequests(token: StateFlow<String?>) {
val interceptor =
MapRequestInterceptor(
headers = { request ->
val currentToken = token.value
if (request.url.startsWith("https://tiles.example.com/") && currentToken != null) {
mapOf("Authorization" to "Bearer $currentToken")
} else {
emptyMap()
}
}
)
val provider = MapResourceProvider(scheme = "app") { request -> readAsset(request.url) }
DefaultMapRuntime.configure {
requestInterceptor = interceptor
resourceProvider = provider
}
}

Attach credentials only to hosts you own. Update the token state to refresh credentials for later callbacks.

For separate configuration, set the hooks in createMapRuntime and pass the result to rememberMapState. Its owner must call MapRuntime.close when finished.

For local tiles, return a MapResourceLoad: Bytes for resource data, NoContent for an empty tile, or Failed with a MapResourceError for an error:

App.kt
val provider =
MapResourceProvider(
accepts = { request -> request.kind == MapResourceKind.Tile },
load = { request ->
try {
when (val bytes = readTile(request.url)) {
null -> MapResourceLoad.NoContent()
else -> MapResourceLoad.Bytes(bytes)
}
} catch (error: Exception) {
MapResourceLoad.Failed(MapResourceError.Server, error.message ?: "tile read failed")
}
},
)