Topolyne

Docs

Everything @topolyne/react can do, demonstrated with the real component against a live published map.

Quickstart

Open the editor, search for a place, pick a preset, and adjust terrain, colors, roads, and labels. Every change is live. Click Publish (you'll need to sign in for that step) to get a map ID like map_Nvm9w6Wn9d.

npm install @topolyne/react
import { Map } from "@topolyne/react";

export default function Page() {
  return <Map mapId="map_Nvm9w6Wn9d" className="h-[500px] w-full" />;
}

That's the whole integration. No MapLibre setup, no vector tile schema, no style JSON. The component fetches your published design and renders it, and stays in sync: change the design in the dashboard, publish again, and every app rendering that mapId picks it up on its next fetch. No rebuild, no redeploy.

Overriding the view

<Map
  mapId="map_Nvm9w6Wn9d"
  center={[7.7491, 46.0207]}
  zoom={15}
  interactive
/>

Markers

Pins you place in the editor (up to 20 per map) are baked into the published design and render automatically — no code needed for those. <MapMarker> is for markers your app adds at runtime instead — a user's live location, a search result, anything driven by your own state. It must be rendered inside <Map>. Pass children to render your own marker instead of the default pin. Click the marker below.

import { Map, MapMarker } from "@topolyne/react";

<Map mapId="map_Nvm9w6Wn9d">
  <MapMarker latitude={46.0207} longitude={7.7419} onClick={() => console.log("clicked")}>
    <MyPin />
  </MapMarker>
</Map>

Route planning

<MapRoute> draws a routed path between two points, real turn-by-turn directions from OpenRouteService, fetched through your own server so the routing API key never reaches the browser. opts.profile defaults to "driving-car"; cycling-regular and foot-walking are also available, plus a waypoints array for stops in between.

Routing…
import { Map, MapRoute } from "@topolyne/react";

<Map mapId="map_Nvm9w6Wn9d">
  <MapRoute
    origin={[7.7419, 46.0207]}
    destination={[7.7486, 46.0192]}
    profile="foot-walking"
    onRoute={({ distanceMeters, durationSeconds }) => {
      console.log(distanceMeters, durationSeconds);
    }}
  />
</Map>

Programmatic control

useTopolyneMap() hands you the live MapLibre GL instance from any component rendered inside <Map>, for anything the config format doesn't cover directly.

import { useTopolyneMap } from "@topolyne/react";

function FlyToButton() {
  const { map, loaded } = useTopolyneMap();
  if (!loaded) return null;
  return (
    <button onClick={() => map?.flyTo({ center: [7.6586, 45.9763], zoom: 12 })}>
      Fly to the Matterhorn
    </button>
  );
}

Props

PropTypeNotes
mapIdstringThe id from Publish in the editor. Required.
className / stylestring / CSSPropertiesApplied to the wrapping div. The map has no intrinsic size.
center[number, number]Override the saved center: [longitude, latitude].
zoom / pitch / bearingnumberOverride the saved view.
interactivebooleanDefaults to true. Set false for a static, poster-style embed.
onLoad(map) => voidCalled once with the live MapLibre instance.
providerMapProviderConfigEscape hatch for a self-hosted instance. Most apps never set this.

Self-hosting

Point the SDK at a different Topolyne instance, a local dev server while building against it, or a self-hosted deployment. Almost no app needs this.

import { configureTopolyne } from "@topolyne/react";

configureTopolyne({ apiBaseUrl: "https://your-topolyne-instance.com" });