React Location Picker: Pin ziehen, Radius, Suche

Du brauchst einen React Location Picker: ein Inseratsformular, das fragt, wo die Wohnung liegt, einen Checkout, der fragt, wo das Paket abgelegt werden soll, eine Suchseite, die nach Entfernung filtert. Ein Textfeld für die Adresse reicht, bis das Gebäude keine Hausnummer hat, der Kurier den Hintereingang braucht oder der Filter „im Umkreis von 10 Meilen“ lautet. Dann brauchst du eine echte Karte mit Pin. Dieser Guide zeigt, was ein Picker können muss und auf welche Props es bei der Location Map von Wingo UI ankommt, und liefert komplette Beispiele für Pin, Radius und Adresssuche.
Was muss ein React Location Picker können?
Sieben Dinge. Wer nach „pick location on map react“ sucht, weil Nutzer einen Standort auf der Karte auswählen sollen, findet meist einen Click-Handler mit useMapEvents aus react-leaflet, der einen Marker setzt. Der deckt nur den ersten Punkt ab. Das ist die Liste, an der wir unseren eigenen React Map Picker messen:
- Drei Wege, den Pin zu setzen. Auf die Karte klicken oder tippen, den Pin ziehen und ihn mit den Pfeiltasten bewegen, sobald er den Fokus hat.
- Suche. Ort oder Adresse eintippen, ein Ergebnis wählen, und die Karte fliegt dorthin.
- Ein Radius für Liefergebiete und Umkreisfilter, mit einem Slider, der den Kreis live anpasst.
- Mein Standort, mit einer ehrlichen Meldung, wenn der Browser ablehnt.
- Seiten-Scrollen, das weiter funktioniert. Eine Karte, die das Mausrad oder ein Wischen mit einem Finger abfängt, hält dich mitten auf der Seite fest.
- SSR-sicheres Laden. Leaflet greift beim Import auf
windowzu, und das lässt ein Server-Rendering in Next.js abstürzen. - Ein Fallback, wenn Kacheln oder der Karten-Chunk nie ankommen: offline, blockiert oder einfach noch nicht ins Bild gescrollt.
Die Punkte 5 und 7 merkst du erst in Produktion. Eine Karte mitten in einem Formular ist am Smartphone eine 300px hohe Fläche, auf der ein Wischen die Karte verschiebt statt die Seite, und eine Karte, die nicht lädt, zeigt einen grauen Kasten ohne jeden Hinweis, wo der Pin war.
Auf welchen React-Karten-Libraries kannst du einen Location Picker bauen?
Leaflet mit OpenStreetMap braucht keinen API-Key, Google Maps und Mapbox brauchen einen Key oder Token und ein Konto. Die Angaben stammen aus der öffentlichen Doku des jeweiligen Projekts, Stand Oktober 2026.
Google ist die bessere Wahl, wenn du die Ortsdaten von Google und weltweite Adress-Autovervollständigung bis auf Straßenebene brauchst und mit der Abrechnung leben kannst. Mapbox passt, wenn du Vektor-Styles willst. Ein React Leaflet Location Picker ist der leichteste Weg zu einem Pin auf einer Karte ohne Konto. Genau darauf baut die Location Map auf: Du bekommst die Kacheln von Leaflet, ohne Klick, Ziehen, Suche und das Verhalten am Smartphone selbst zu schreiben.
Welche Props braucht die Location Map?
Einen Wert (value) und ein onValueChange. Der Wert ist ein GeoPoint ({ lat, lng }) oder null, solange noch kein Pin gesetzt ist. Die Karte ruft onValueChange auf, wenn ein Ziehen endet, ein Klick den Pin setzt, ein Suchergebnis oder der Standort-Button ihn verschiebt oder die Eingabe per Tastatur kurz ruht.
Die CLI kopiert components/ui/location-map.tsx samt den Komponenten und Helfern, die die Datei importiert, und installiert leaflet, motion und lucide-react.
$ npx wingo-ui@latest add location-mapDie eingebaute Suche läuft offline und kennt rumänische Orte, Gebiete und Kreise aus ro-locations, deshalb zeigt die Demo oben Cluj-Napoca. Für eine App in den USA übergibst du ein Zentrum und einen Geocoder, der dein Land kennt:
nominatimGeocoder setzt countryCodes standardmäßig auf "ro", also gib es an (oder übergib "" für die ganze Welt). Der Reverse Geocoder benennt den Pin 500ms, nachdem er zum Stehen gekommen ist, mit Straße und Ort. Ohne ihn zeigt die Ortszeile ersatzweise den nächstgelegenen rumänischen Ort, und außerhalb Rumäniens nur die Koordinaten.
Die anderen Props, die du brauchen wirst: defaultZoom (13 zeigt ein Viertel, 16 eine Straße), draggable und clickToPlace (beide standardmäßig an), readOnly für eine Filialseite, die nur zeigt, wo der Laden ist, searchable und locate, um das Suchfeld oder den Standort-Button auszublenden, und height (standardmäßig 320px).
Wie füge ich der Karte einen Radius hinzu?
Übergib einen Radius in Kilometern. Ein Radius für Liefergebiete oder „Inserate in der Nähe“ ist einfach ein weiterer kontrollierter Wert: radius und onRadiusChange, dazu radiusRange und radiusStep für den Slider unter der Karte. null oder 0 blendet Kreis und Slider aus.
onRadiusChange feuert bei jedem Schritt des Sliders, und die Ansicht passt sich dem Kreis an, sobald du loslässt. Zeichnest du die Zone selbst mit reinem Leaflet, denk daran, dass L.Circle Meter erwartet, keine Kilometer. showTownsInRadius ergänzt eine Anzeige wie „14 towns in range“ aus der rumänischen Ortsliste, außerhalb Rumäniens schaltest du es also ab. Der Slider unter der Karte ist derselbe, den du in Formularen nutzt.
Wie suche ich nach einer Adresse?
Übergib einen geocoder: eine Funktion, die die Suchanfrage und { signal, locale } bekommt und GeocodeResult[] zurückgibt (id, label, optional description, point, optional bounds). Die Karte entprellt das Tippen, bricht die vorherige Anfrage über das Signal ab und passt die Ansicht an bounds an, wenn ein Ergebnis sie mitliefert. Die Ergebnisliste ist der Search Input mit Pfeiltasten und Enter.
nominatimGeocoder reicht für einen Prototyp. Die Nominatim Usage Policy (opens in a new tab) von OpenStreetMap erlaubt höchstens eine Anfrage pro Sekunde und schließt Autovervollständigung im Client aus. Der Helfer drosselt die Anfragen per Warteschlange auf eine pro Sekunde, aber ein Suchfeld, das beim Tippen abfragt, ist trotzdem genau der Fall, vor dem die Policy warnt. Für die Produktion lässt du den Geocoder auf deine eigene Route zeigen. Die kann jeden Anbieter aufrufen, Antworten cachen und den Key auf dem Server halten:
Wirft der Geocoder einen Fehler, zeigt die Liste „No places found“ statt einer Fehlermeldung. Wenn du zusätzlich eine Adresse als Text erfasst, ergänzen sich Pin und Formularfelder: Der Address Input enthält Straße und Hausnummer, die Karte den genauen Punkt. Der Guide zum rumänischen Adressformat zeigt dieses Formular Teil für Teil, und der Guide zur React Combobox erklärt die Tastaturregeln, denen die Ergebnisliste folgt.
Wie verhält sich der Picker am Smartphone?
Die eingebettete Karte nimmt der Seite das Scrollen nicht weg. Mit interactive="auto" (Standard) ist die Karte mit der Maus direkt an Ort und Stelle bedienbar. Auf Touch-Geräten öffnet ein Tippen ein Sheet in voller Höhe, mit der Suche oben, einer Karte, die du per Pinch zoomen, ziehen und antippen kannst, und unten dem Button „Done“. Schließt du das Sheet auf andere Weise, wird die Änderung verworfen. So verschiebt ein versehentliches Wischen den Pin nie. Eingebettet zeigt ein Smartphone höchstens 220px Karte, denn die volle Karte ist nur ein Tippen entfernt.
interactive="always" macht die Karte überall direkt bedienbar, und interactive="expand" öffnet immer das Sheet (am Desktop einen Dialog), was zu einer kompakten Formularzeile passt. Das Sheet ist der Drawer; der Guide zum React Bottom Sheet erklärt, warum Sheets unter 768px besser sind als Popover. Am Desktop zoomt das Mausrad mit scrollWheelZoom="focus" erst, nachdem du in die Karte geklickt hast, und hört auf, sobald der Zeiger sie verlässt. So bleibt das Scrollen an der Karte vorbei nie an ihr hängen.
Ist der Location Picker barrierefrei?
Ja, jede Bewegung geht auch per Tastatur. Tab erreicht die Suche, die Karte (Pfeiltasten verschieben, Plus und Minus zoomen), den Pin (Pfeiltasten bewegen ihn um 10px, Shift plus Pfeiltaste um 50px, übernommen wird kurz nach der letzten Taste), die Karten-Buttons und den Slider. Für Screenreader beschreiben der Ortsname und die Koordinaten darunter die Karte, und eine Live Region sagt jede Bewegung als „Pin moved: ...“ an. Jeder Text, Ansagen eingeschlossen, steckt in labels und überschreibt die Werte aus DEFAULT_LOCATION_MAP_LABELS, so übersetzt du alles, ohne die Datei zu forken. Reduced Motion schaltet die Fall-Animation des Pins und die animierten Flüge der Karte ab.
Was passiert, wenn die Karte nicht lädt?
Eine gezeichnete statische Ansicht springt ein: eine Skizze des Viertels mit Pin, Radius-Ring und einem Chip mit Ort und Koordinaten. Du siehst sie, bevor die Karte lädt (mit lazy lädt Leaflet erst, wenn die Karte bis auf 200px an den Viewport herankommt), wenn der Browser offline ist, wenn mehr als sechs Kacheln nacheinander fehlschlagen und wenn der Karten-Chunk nicht lädt. Leaflet wird in einem Effect importiert, nie auf Modulebene, deshalb rendert die Komponente auf dem Server ohne next/dynamic.
staticOnly lässt die Karte ganz weg. Für eine E-Mail, eine Druckansicht, ein Thumbnail oder eine Liste mit fünfzig Filialen nimmst du StaticMap direkt: Sie braucht keine Karten-Library und kein Netzwerk.
$ npx wingo-ui@latest add location-mapWelche typischen Fehler gibt es bei einem Location Picker?
Vier Fehler tauchen auf, sobald ein Picker die Demo verlässt.
- Mit den öffentlichen OSM-Kacheln live gehen. Die Tile Usage Policy (opens in a new tab) hat kein SLA und kann starke Nutzung sperren. Setz
tileUrlauf die Raster-Kacheln deines Anbieters undattributionauf den Hinweis, den er verlangt. - Rumänische Standardwerte beibehalten. Ohne Props zentriert die Karte auf Cluj-Napoca, sucht offline nach rumänischen Orten, zählt rumänische Orte im Radius, und
nominatimGeocoderbeschränkt die Ergebnisse auf"ro". Eine App für die USA setztcenter,geocodermitcountryCodes,reverseGeocoderundshowTownsInRadius={false}, wie in den Beispielen oben. - Bei jedem Slider-Schritt speichern.
onRadiusChangefeuert pro Schritt; speichere beim Absenden oder entprell den Aufruf. - Dark Mode ohne Plan.
darkTiles="filter"invertiert die hellen Kacheln im Dark Mode ohne zweiten Anbieter;"url"wechselt aufdarkTileUrl, und"none"behält in beiden Themes die hellen Kacheln.
Wie baue ich die Komponente in mein Projekt ein?
Führ npx wingo-ui@latest add location-map aus. Die Location Map ist eine Pro-Komponente (Preise); Search Input und Drawer, auf denen sie aufbaut, sind kostenlos. Weitere Deep Dives zu einzelnen Komponenten findest du in der Kategorie Komponenten-Guides, und der Guide zu React-Formularkomponenten wendet dieselben Regeln für Touch, Tastatur und Screenreader auf jedes Formularelement an.
Häufige Fragen
Wie bekomme ich in React Breiten- und Längengrad, wenn jemand auf die Karte klickt?
In react-leaflet liest du den Klick mit dem Hook useMapEvents und speicherst e.latlng im State. Die Location Map von Wingo UI nimmt dir das ab: Ein Klick setzt den Pin und onValueChange bekommt { lat, lng }.
Warum wirft Leaflet in Next.js „window is not defined“?
Leaflet liest window schon beim Import des Moduls, deshalb stürzt ein Import in Code ab, der auf dem Server läuft. Lade es nur im Browser, entweder mit next/dynamic und ssr: false aus einer Client-Komponente oder mit einem dynamischen Import in einem Effect, so wie die Location Map es macht.
In welcher Einheit gibt man den Radius eines Leaflet-Kreises an?
L.Circle von Leaflet erwartet den Radius in Metern. Der radius-Prop der Location Map ist in Kilometern und rechnet für dich um.
Kann ich OpenStreetMap-Kacheln und Nominatim in Produktion nutzen?
Nur bei geringer Last. Die Tile Policy von OSM gibt kein SLA und kann starken Traffic sperren, und die Nominatim-Policy erlaubt höchstens eine Anfrage pro Sekunde und keine Autovervollständigung im Client. Apps in Produktion sollten tileUrl und den Geocoder deshalb auf einen eigenen Anbieter zeigen lassen.
Ist die Location Map von Wingo UI kostenlos?
Nein, die Location Map ist eine Pro-Komponente. Search Input und Drawer, auf denen sie aufbaut, sind kostenlos.
- Karten
- Standort
- Leaflet
- Mobile UI
- React


