TileflowDocs

Static maps

Generate map images from the same deployed style

Static maps render deterministic PNGs for docs, Open Graph images, emails, reports, and visual tests. They use the same named maps and style revisions as your interactive Tileflow maps.

1

Describe the scene

A static scene names the map, chooses a camera, sets a size, and optionally adds overlays. Use @tileflow/static helpers to normalize and validate the shape before it reaches the API.

static-scene.ts
import { marker, validateStaticScene } from "@tileflow/static";
 
const validation = validateStaticScene({
  map: "madrid",
  camera: {
    type: "center",
    center: [-3.7038, 40.4168],
    zoom: 12,
  },
  size: {
    width: 1200,
    height: 800,
  },
  overlays: [
    marker({
      coordinate: [-3.7038, 40.4168],
      color: "#C6A15B",
    }),
  ],
});
 
if (!validation.ok) {
  throw new Error(validation.error);
}
 
const scene = validation.scene;
2

Render from a server route

Keep the API key on the server. createStaticMap posts the scene to/v1/static/maps and returns an immutable image URL plus cache metadata.

app/api/maps/static/route.ts
import { createStaticMap, marker } from "@tileflow/static";
 
export async function POST() {
  const result = await createStaticMap(
    {
      map: "madrid",
      camera: {
        type: "center",
        center: [-3.7038, 40.4168],
        zoom: 12,
      },
      size: { width: 1200, height: 800 },
      overlays: [marker({ coordinate: [-3.7038, 40.4168] })],
    },
    {
      apiKey: process.env.TILEFLOW_API_KEY,
    },
  );
 
  return Response.json(result);
}
3

Render the image in React

@tileflow/react/static deduplicates in-flight requests and renders a stable image box with the scene aspect ratio.

MadridImage.tsx
import { StaticMap } from "@tileflow/react/static";
import { marker } from "@tileflow/static";
 
export function MadridImage() {
  return (
    <StaticMap
      createUrl="/api/maps/static"
      map="madrid"
      camera={{
        type: "center",
        center: [-3.7038, 40.4168],
        zoom: 12,
      }}
      size={{ width: 1200, height: 800 }}
      overlays={[marker({ coordinate: [-3.7038, 40.4168] })]}
      alt="Madrid map"
    />
  );
}

Public shortcut

Use a URL for simple center/zoom images

For local development and self-hosting, a convenience PNG shortcut accepts center, zoom, bearing, width, and height. The hosted production API disables on-demand public renders: call the authenticated server API and then serve its immutable image URL.

Development/self-hosting URL
# Development/self-hosting only; production returns 403.
http://localhost:8787/maps/map_1234567890abcdef/static.png?center=-3.7038,40.4168&zoom=12&width=1200&height=800

Routes

Static map endpoints

Authenticated render routes create or warm cached images. The content-addressed output route serves generated PNGs publicly; the convenience redirect is development-only.

GET/maps/:mapId/static.png

Convenience PNG shortcut; disabled on the hosted production API.

GET/static-maps/v1/:hash.png

Immutable generated PNG served from the static map cache.

POST/v1/static/maps

Create or reuse a deterministic static map image from scene JSON.

POST/v1/static/maps/precache

Idempotently warm the cache for the same static map scene.

Limits

Bounds that keep renders predictable

Static scenes are intentionally bounded so renders stay cacheable, fast, and safe to generate from app workflows.

Image size64-1280 px per side
Pixel budget1280 x 1280 physical pixels
OverlaysUp to 24 overlays per scene
PathsUp to 2000 coordinates per path
Overlay JSONUp to 96 KB
Cameracenter/zoom or bounds/padding