Maps & vector tiles
env.MAP puts an interactive map with your own data on it. You store GeoJSON sources, and Cloudrizz serves them as vector tiles and hands you a ready-made MapLibre style — no tile server to run and no API keys to manage. Available on every plan.
Add your data
A source is a named GeoJSON FeatureCollection (or a single Feature / geometry). Store one from any api/*.js route; calling putSource again with the same name replaces it. Up to 50 MB per source.
// api/seed.js — load a source (e.g. from an admin route, run once)
export default {
async fetch(request, env) {
await env.MAP.putSource("stores", {
type: "FeatureCollection",
features: [
{ type: "Feature", properties: { name: "HQ" },
geometry: { type: "Point", coordinates: [10.75, 59.91] } },
],
});
return new Response("seeded");
},
};Show the map
Point MapLibre at your app's style URL — it already includes a basemap plus a layer for every source you've added. Get the URL from env.MAP.styleUrl() (no network call — it's just a string):
// api/mapstyle.js — hand the browser this app's style URL
export default { async fetch(request, env) { return new Response(env.MAP.styleUrl()); } };<!-- index.html -->
<link href="https://unpkg.com/maplibre-gl/dist/maplibre-gl.css" rel="stylesheet" />
<script src="https://unpkg.com/maplibre-gl/dist/maplibre-gl.js"></script>
<div id="map" style="height:100vh"></div>
<script>
fetch("/api/mapstyle").then((r) => r.text()).then((style) => {
new maplibregl.Map({ container: "map", style, center: [10.75, 59.91], zoom: 10 });
});
</script>By default points render as circles, lines as strokes, and polygons as a translucent fill, so any geometry shows up without extra work.
API
putSource(name, geojson)— create or replace a source (tiles regenerate on the next request).deleteSource(name)·listSources()→{ sources: [...] }.styleUrl()— the MapLibre style URL (basemap + all your sources).tileUrl(name)— the raw vector-tile URL template for one source, for building your own MapLibre style. Itssource-layeris"data".
putSource is for smaller datasets (it builds the tile index in memory). For large datasets — tens of thousands up to millions of features — store them with env.GEO instead; those render on the map the same way (via styleUrl()) but tile straight from PostGIS, so they scale far higher.
Querying geometry
env.MAP stores and displays geometry. For spatial queries — "what's within 5 km of here", "which zone contains this point" — use env.GEO, the PostGIS-backed query tier. Its results come back as GeoJSON, so you can feed them straight into putSource to draw them.