# Embedding with the JavaScript SDK

Drive an embedded map from your own site: send your search filters in and react when visitors select a pin.

The iframe snippet from [Sharing & embedding your map](/help/sharing-your-map) is the fastest way to put a map on a website. If your site needs to *talk to* the map (push its own search filters in, or react when a visitor picks a pin), use the JavaScript SDK instead. It's a small script with no dependencies, aimed at developers.

The SDK powers things like a product search page where the results list and the map stay in sync: the page sends its current filters to the map, the map shows matching pins, and clicking a pin takes the visitor to the page's own detail view.

## Load the SDK and create a map

```html
<div id="map"></div>
<script src="https://sawyoursign.com/sdk/v1.js"></script>
<script>
  const map = await SawYourSignMap.create({
    element: document.getElementById('map'),
    slug: 'your-workspace-slug',
    map: 'default', // or a saved map's share token
  })
</script>
```

The map must have **Allow embedding on other sites** checked and visibility **Public** or **Unlisted** (set both in the map's Sharing settings).

## Send filters from your page

```js
map.updateFilters({
  state: 'RI',                // single value
  services: ['repair'],       // any of several values
  rating: { op: 'num', cmp: 'gte', value: 4 },  // full operator form
}, { q: 'wheel builds' })     // optional free-text search
```

You're sending **filter state, not data**: Saw Your Sign checks every key against the map's filterable fields and resolves the matching pins on its own servers. Keys that aren't filterable on that map are ignored. On a [bridge-backed map](/help/external-data-maps), the filter keys are the bridge's field keys.

## React to map events

```js
map.on('select', record => {
  // { id, slug, title, lat, lng }: open your own detail page
  location.href = '/listings/' + record.slug
})
map.on('viewport', v => console.log(v.center, v.zoom, v.bounds))
map.on('lead', lead => { /* a visitor sent the lead form */ })
```

`on` returns an unsubscribe function; `map.destroy()` removes the map.

## Headless embeds: show only the map

When your page already has its own search box, filters, and results list, you usually want the embed to be **just the map**, with none of Saw Your Sign's own chrome. Pass a `view` object to hide any piece and to relabel the record button:

```js
const map = await SawYourSignMap.create({
  element: document.getElementById('map'),
  slug: 'your-workspace-slug',
  view: {
    header: false,    // hide the branded header bar
    search: false,    // hide the address / text search
    filters: false,   // hide the filter chips
    sidebar: false,   // hide the record list
    ctaLabel: 'View details', // relabel the record's button
  },
})
```

Every key is optional. Each one resolves as **embed setting, then the map's own default, then shown**: anything you leave out falls back to the map's dashboard settings (see [Customizing your map](/help/customizing-your-map)). So you can set sensible defaults once on the map and still override them for a specific embed.

This pairs naturally with a deep-linked record button. Set the map's **Lead button link** (in its General settings) to your own detail URL with a `{slug}` or `{id}` placeholder, for example `https://example.com/listings/{slug}`, and relabel the button with `ctaLabel`. A visitor who picks a pin sees the in-map detail and a button that takes them to your page.

## Reference

The full option and event reference (heights, multiple maps per page, the React pattern, every filter operator) lives in the repository's `docs/sdk.md`. The classic `embed.js` snippet keeps working unchanged; the SDK is for sites that need programmatic control.
