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.
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.
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;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.
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);
}Render the image in React
@tileflow/react/static deduplicates in-flight requests and renders a stable image box with the scene aspect ratio.
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 only; production returns 403.
http://localhost:8787/maps/map_1234567890abcdef/static.png?center=-3.7038,40.4168&zoom=12&width=1200&height=800Routes
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.
/maps/:mapId/static.pngConvenience PNG shortcut; disabled on the hosted production API.
/static-maps/v1/:hash.pngImmutable generated PNG served from the static map cache.
/v1/static/mapsCreate or reuse a deterministic static map image from scene JSON.
/v1/static/maps/precacheIdempotently 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.