Documentation

tileserver-rs uses the trailing slash to distinguish API endpoints from the built-in web viewer. The same path with and without a trailing slash can be two different things:

PathWhat it serves
/styles/protomaps-lightStyle JSON (API)
/styles/protomaps-light/Map viewer UI (SPA)
/data/protomapsTileJSON (API)
/data/protomaps/Data inspector UI (SPA)

Normalization rules

Every request path is normalized before routing:

  • API paths are trimmed — /health/, /ping/, /data.json/, /styles.json/, /_openapi/ and any other slashed API path serve the same response as their canonical slash-less form. Curl either; both work.
  • SPA viewer paths are preserved — exactly two families keep their trailing slash: /styles/{id}/ and /data/{id}/. These fall through to the embedded web UI (the frontend feature) instead of the greedy API routes.

This means "Open in viewer" and "Inspect" links from the home page (/styles/{id}/ and /data/{id}/) are stable, shareable URLs — including query flags like /styles/{id}/?raster — while every API consumer gets canonical, slash-insensitive endpoints.

Info

Implementation lives in crates/tileserver-rs/src/trailing_slash.rs — a selective layer applied outside the router. A blanket trim would collapse the viewer routes onto the API routes and 404 every viewer link; the selective layer exists precisely to prevent that regression.