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. Its source-layer is "data".
Tiles are served from a shared, edge-cached endpoint, so a map with thousands of features stays fast and cheap. Map display data is public — don't put anything private in a source.

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.