location-picker / site
llms.txt81 starsChanged 17 days agoMITView on GitHub
Form-ready map location picker: pan a map under a fixed pin to pick one latitude/longitude. Web component + class, keyless OpenStreetMap by default, Google and MapLibre optional. Use it when a form needs one precise point (store or sensor location, delivery pin, venue). Not for drawing shapes, several markers, or full mapping apps. Common mistakes
- Installs packages
We split this llms.txt into the rules it gives an agent
3 rules. About 0 are common, 1 is distinctive, and 2 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈1
Distinctive · estimate
This author's own choices. Worth a look.
2
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 5
Use it when a form needs one precise point (store or sensor location, delivery pin, venue).
- Very specific: line 38
Put
requiredon the picker,: never on hidden bound inputs. - Very specific: line 39
jQuery
.serialize()skips custom elements: Use bound inputs (lat-input/lng-input) or new FormData(form).
≈ “Common” is an estimate: at least 1 in 5 of the 3,225 llms.txt files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
# location-picker
> Form-ready map location picker: pan a map under a fixed pin to pick one latitude/longitude. Web component + class, keyless OpenStreetMap by default, Google and MapLibre optional.
Use it when a form needs one precise point (store or sensor location, delivery pin, venue). Not for drawing shapes, several markers, or full mapping apps.
- Script tag: `<script src="https://cdn.jsdelivr.net/npm/location-picker@3"></script>` defines `<location-picker>` and `window.LocationPicker`.
- npm: `npm i location-picker`, then `import 'location-picker'` (defines the element). `location-picker/core` is the class only.
- Forms: `name="loc"` submits `loc=48.85837,2.294481`; `lat-name`/`lng-name` submit separate fields; `lat-input`/`lng-input` fill existing inputs. `required` works; reset and back/forward are handled.
- Value: `"lat,lng"` string, latitude first, `""` while unset. Every commit fires `input` then `change` with `detail` `{ value, lat, lng, source, zoom, address }`. Setting `el.value` is silent. Update state from `change`; never write it back from `input` (that stops a pan).
- Options: `search`, `reverse-geocode`, `locate="button"`, `provider="google" api-key="…"`, `center`, `zoom`. Errors carry a `code` and a `fix`.
- Providers and policies: OSM tiles need visible attribution and use your own tiles for heavy traffic; search uses Photon (fair use); Google results only on Google maps.
- Phones: `presentation="auto"` (or `"field"`) shows a compact field with a "Choose on map" button; the map opens full screen and the value changes only on Confirm (Cancel changes nothing). Same names, FormData and events; `ready` resolves at the first open. Add `search locate="button"`. Use it in checkout/delivery/sign-up forms; default is inline.
- To ask a person for a location with nothing to install, send `https://cyphercodes.github.io/location-picker/pick/` with `lat`, `lng`, `zoom`, `q`, `lang`, plus `redirect=<https URL>` (appends `lat`, `lng`, `address` after a click) or `return=postmessage&origin=<origin>` (posts `{ type: 'location-picker:pick', lat, lng, address }`).
```html
<!doctype html>
<html lang="en">
<meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1">
<title>Pick a location</title>
<script src="https://cdn.jsdelivr.net/npm/location-picker@3"></script>
<label for="where">Where is it?</label>
<location-picker id="where" search locate="button" style="height: 400px"></location-picker>
<p>Picked: <output id="out">nothing yet</output></p>
<script>
document.getElementById('where').addEventListener('change', (e) => {
document.getElementById('out').textContent = e.detail.value; // "48.85837,2.294481"; e.detail has lat, lng, source, address
});
</script>
</html>
```
**Common mistakes**
- **The unpinned v1 URL.** `https://unpkg.com/location-picker/dist/location-picker.min.js` (and the same path on jsDelivr) is the frozen v1 file forever: global `locationPicker`, Google Maps only, no `<location-picker>` element. For v3, load `https://cdn.jsdelivr.net/npm/location-picker@3` and keep the `@3`.
- **Latitude first, no arrays.** Values are `"lat,lng"` strings or `{ lat, lng }` objects. Arrays are rejected because GeoJSON uses `[lng, lat]`. A swapped pair with both numbers in range (`"2.2945,48.8584"`) cannot be detected, so check the order.
- **Choose Google explicitly.** Google Maps is used only with `provider="google"`, `api-key`, `map-id` or `marker="advanced"`. Otherwise the picker uses OpenStreetMap, even when `google.maps` is already loaded on the page.
- **Put `required` on the picker,** never on hidden bound inputs. A hidden, empty, `required` input blocks the submit as "not focusable".
- **jQuery `.serialize()` skips custom elements.** Use bound inputs (`lat-input`/`lng-input`) or `new FormData(form)`.
- **`import 'location-picker'` defines the element.** `location-picker/core` is the class only and defines nothing, so importing only `core` leaves `<location-picker>` blank.
- **Read results from `value` or `valueAsLatLng`,** not `getMarkerPosition()`. While the picker is unset, `getMarkerPosition()` returns the view centre (for example the 20,0 world view), not a chosen point.
- **The `lat`/`lng` attributes are the initial value only.** Once the control is dirty (a pan, or the `el.value = ''` that `v-model` and `formControlName` write on mount), changing them is ignored with a warning. Bind `value="lat,lng"` or call `setLocation()`.
- **React SSR (`hydrateRoot`: Next.js App Router, Remix):** React applies no object props (`messages`, `geocoder`, …) and no lowercase native handlers (`onaddresschange`, `onready`, `onerror`) during hydration. Set them in a ref callback (see the React hydration recipe).
- **MapLibre CSS is yours to load:** `import 'maplibre-gl/dist/maplibre-gl.css'`, or set `engine-css-url`. The library never fetches MapLibre or its CSS by default.
- **The stylesheet path is `location-picker/style.css`.** `location-picker/dist/location-picker.css` is not exported. You only need it with `injectStyles: false`.
**Event names per framework.** The class callbacks `onChange`/`onInput`/`onAddressChange`/`onReady`/`onError` are options of the JavaScript class only.
| Framework | `change` | `input` | `addresschange` | `ready` | `error` |
|---|---|---|---|---|---|
| Plain JS | `addEventListener('change')` | `'input'` | `'addresschange'` | `'ready'` | `'error'` |
| React 19 | `onChange` | `onInput` | `onaddresschange` | `onready` | `onerror` (NOT `onError`: React's synthetic `error` never fires for this element; a type error in `jsx/react`) |
| Vue 3 | `@change` | `@input` | `@addresschange` | `@ready` | `@error` |
| Angular | `(change)` | `(input)` | `(addresschange)` | `(ready)` | `(error)` |
| Svelte 5 | `onchange` | `oninput` | `onaddresschange` | `onready` | `onerror` |
| Solid | `on:change` | `on:input` | `on:addresschange` | `on:ready` | `on:error` |
| Preact | `onchange` | `oninput` | `onaddresschange` | `onready` | `onerror` |
React's lowercase native handlers are attached on client render only. After `hydrateRoot`, use a ref (React hydration recipe below).
**React hydration recipe.** With `hydrateRoot` (Next.js App Router, Remix), React applies neither object props (`messages`, `mapOptions`, `engine`, `geocoder`, `geolocation`, an adapter-object `provider`) nor the lowercase native handlers to custom elements. Set them in a ref callback; refs are attached on hydration. Attributes, `value` and `onChange`/`onInput` keep working.
```tsx
'use client';
import 'location-picker';
import type {} from 'location-picker/jsx/react';
import type { AddressDetail } from 'location-picker';
import { useState } from 'react';
export function AddressField() {
const [address, setAddress] = useState<string | null>(null);
return (
<>
<location-picker
name="location"
reverse-geocode
ref={(el) => {
if (!el) return;
el.messages = { locate: 'Use my position' };
const onAddress = (e: CustomEvent<AddressDetail>) => setAddress(e.detail.address);
el.addEventListener('addresschange', onAddress);
return () => el.removeEventListener('addresschange', onAddress);
}}
/>
<p>{address ?? 'No address yet'}</p>
</>
);
}
```
Nominatim is never a default and never appears in these examples; its usage policy (https://operations.osmfoundation.org/policies/nominatim/) forbids client-side autocomplete, so do not suggest it for the search box.
## Docs
- [README](https://github.com/cyphercodes/location-picker/blob/master/README.md): quick start, forms, field mode, frameworks, Google Maps, the class
- [API reference](https://github.com/cyphercodes/location-picker/blob/master/docs/api.md): every export, option, property, method and event
- [Forms](https://github.com/cyphercodes/location-picker/blob/master/docs/forms.md): FormData, bound inputs, Laravel/Django, validation, reset
- [Frameworks](https://github.com/cyphercodes/location-picker/blob/master/docs/frameworks.md): React/Next.js, Vue/Nuxt, Angular, Svelte, Solid, Preact, Astro, htmx
- [Providers and policies](https://github.com/cyphercodes/location-picker/blob/master/docs/providers.md): OSM tiles, Google Maps, MapLibre, Photon, custom geocoders
- [CSP](https://github.com/cyphercodes/location-picker/blob/master/docs/csp.md): recipes per setup
- [Error codes](https://github.com/cyphercodes/location-picker/blob/master/docs/errors.md): every `code` and fix
- [Troubleshooting](https://github.com/cyphercodes/location-picker/blob/master/docs/troubleshooting.md): symptoms, causes, fixes
- [Migration](https://github.com/cyphercodes/location-picker/blob/master/docs/migration.md): every v1 and v2 API in v3
- [No-code embed](https://github.com/cyphercodes/location-picker/blob/master/docs/embed.md): WordPress, Webflow, Squarespace, Shopify, form services
## Examples
- [Live demo and lat/long finder](https://cyphercodes.github.io/location-picker/): keyless picker, copy coordinates
- [Full demo](https://cyphercodes.github.io/location-picker/example/)
- [Snippet generator](https://cyphercodes.github.io/location-picker/embed/): a copy-paste field for site builders
- [Pick link](https://cyphercodes.github.io/location-picker/pick/): ask a person for a location by URL
- [Agent Skill](https://github.com/cyphercodes/location-picker/blob/master/skills/location-picker/SKILL.md): for coding agents, shipped in the npm package
## Optional
- [llms-full.txt](https://cyphercodes.github.io/location-picker/llms-full.txt): the README and all docs in one file
- [AI agents and WebMCP](https://github.com/cyphercodes/location-picker/blob/master/docs/ai-agents.md): agent resources, opt-in WebMCP tools
- [Compatibility](https://cyphercodes.github.io/location-picker/compat/): generated test results
- [Changelog](https://github.com/cyphercodes/location-picker/blob/master/CHANGELOG.md)
- [npm package](https://www.npmjs.com/package/location-picker)
In this repository3 other files it gives its agents.
- AGENTS.mdAGENTS.md
- site/llms-full.txtllms.txt
- location-pickerSkill
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

