Documentation menu
Example
Vector tiles you host as PMTiles
Put a large dataset on the map as vector tiles from one PMTiles file on your own bucket: no tile server, no upload to us. The browser reads only the byte ranges it needs, so a file of gigabytes draws as fast as a small one.
ts
import { createMap, registerPmtilesProtocol } from "@mapmap/maps";
import * as maplibregl from "maplibre-gl";
// createMap already registers pmtiles:// on the maplibre-gl it imports.
// Call this yourself only for a maplibregl.Map you construct directly, or
// a second copy of maplibre-gl in your bundle. It is safe to repeat.
registerPmtilesProtocol(maplibregl);
const map = createMap({
container: "map",
apiKey: "snk_...",
attributionPosition: "bottom-left",
center: [-0.12, 51.51],
zoom: 11,
});
await map.whenReady();
map.map.addSource("assets", {
type: "vector",
// pmtiles:// in front of the https URL of the file on your bucket.
url: "pmtiles://https://your-bucket.example.com/assets.pmtiles",
attribution: "(c) Example Council 2026",
});
// source-layer is the layer name inside the archive (--layer when you
// built it). Slots arrive in the SDK 0.17: map.slot("middle") replaces
// "road-labels".
map.map.addLayer({
id: "assets-lines",
type: "line",
source: "assets",
"source-layer": "assets",
filter: ["==", ["geometry-type"], "LineString"],
paint: { "line-color": "#e07b39", "line-width": 2.5 },
}, "road-labels");
map.map.addLayer({
id: "assets-points",
type: "circle",
source: "assets",
"source-layer": "assets",
filter: ["==", ["geometry-type"], "Point"],
paint: { "circle-radius": 4, "circle-color": "#e07b39" },
}, "road-labels");Worth knowing
- The bucket's CORS rule must allow GET from your site's origin, allow the Range and If-Match request headers, and expose ETag. Without the Range header allowed, every browser read fails its preflight.
- Replace a published archive under a new file name rather than overwriting it in place. A cached client revalidating ranges against a changed file gets a full 200 body and the read fails.
- There is no hosted tileset upload on MapMap: the file stays on your bucket and is read straight from there by the browser. We store nothing.