ClipSpacesClipSpaces Docs
Back to app

All releases

Map cards (free, no key — MapLibre/OSM + optional Google)

Added a map card kind. It works with no API key: MapLibre GL + OpenStreetMap tiles, geocoded via OSM Nominatim. If a Google key is configured it transparently upgrades new cards to the Google Maps Embed API. First step toward Claude-style place widgets.

Added

  • maplibre-gl dependency.
  • map card kind (lib/canvas-store.ts) with a provider field (maplibre | google) + components/cards/MapCard.tsx:
    • MapLibre/OSM (default) — interactive map centered on lat/lng with a marker; maplibre-gl is lazy-imported in an effect (SSR-safe). Shows a "locating…" spinner while geocoding and a graceful "couldn't find" state.
    • Google — Embed API iframe (place/search/view); placeholder if the key is unset.
    • Cloud persistence is automatic (generic kind + data jsonb — no schema change).
  • GET /api/geocode — free, keyless geocoding via OSM Nominatim (cached 24h, identifying User-Agent per their usage policy).
  • Two creation paths (components/Canvas.tsx):
    • Paste/drop a Google Maps URLgetMapEmbed parses /maps/place/…, /maps/search/…, ?q=, and @lat,lng (routed ahead of the generic unfurl). Coordinates from @lat,lng skip geocoding. Short goo.gl links fall through to a link card.
    • Right-click → "Add map…"addMap(query) geocodes the place/address and drops a map card.
  • AI awareness (app/api/ai/route.ts) — cardLabel / describeCard describe map cards so the assistant reasons over them.

Notes

  • MapLibre uses OSM's public tile server + Nominatim — fine for dev / low volume; both have usage policies, so production should move to MapTiler/Carto/self-host.
  • The Google upgrade key is optional and must be the public, referrer-restricted key (it ships in the iframe URL). See .env.example.