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.

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

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(
MapRuntimeOptions(requestInterceptor = interceptor, resourceProvider = provider)
)
}

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

For separate configuration, use 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")
}
},
)