> ## Documentation Index
> Fetch the complete documentation index at: https://docs.loci.ng/llms.txt
> Use this file to discover all available pages before exploring further.

# Web SDK

> loci-sdk: an embeddable map for the browser. One function call gives you datasets with colours and labels, choropleths, a place filter, drawing with area analysis, and export — scoped to your API key.

`loci-sdk` is a JavaScript package that puts a full LOCI map in any web page. Your users explore the datasets your key can read — toggles, colours, feature labels, choropleths with a legend, a State → LGA → Ward filter — draw work areas, analyse them, and export the result. It is plain JavaScript with TypeScript types: no framework required, and nothing to configure beyond a key.

Your LOCI key is all you need. The SDK borrows the deployment's Mapbox token while the map loads, so there is no second account to set up; pass your own `mapboxToken` only if you want to pin one.

> [card] [The map](https://docs.loci.ng/sdks/web-maps.md)
>
> Datasets, labels, the place filter, frames, drawing, analysis and export.

> [card] [Authentication](https://docs.loci.ng/authentication.md)
>
> Mint a scoped read key. The SDK sends it on every request.

> [card] [npm: loci-sdk](https://www.npmjs.com/package/loci-sdk)
>
> The package, with types. Mapbox GL is a peer dependency.

> [card] [Flutter SDK](https://docs.loci.ng/sdks/flutter-overview.md)
>
> The mobile map, for field data collection in Dart.

## Install

```sh theme={null}
npm install loci-sdk mapbox-gl @mapbox/mapbox-gl-draw
```

`mapbox-gl` (3 or later) and `@mapbox/mapbox-gl-draw` are peer dependencies — your app provides them, so there is never a second copy of Mapbox on the page. Styles are bundled and self-injected: there is no CSS file to import.

```ts main.ts theme={null}
import { createLociMap } from "loci-sdk";

const controller = await createLociMap(document.getElementById("map")!, {
  baseUrl: "https://api.loci.ng",
  auth: { apiKey: "loci_sk_…" }, // a scoped read key from your LOCI org
});
```

The container just needs a size (`width`/`height`); the widget fills it.

## No build step: the hosted embed

The LOCI API serves the same widget as a single self-contained script — Mapbox, styles and all — so any page can embed a map with one tag:

```html embed.html theme={null}
<div id="loci-map" style="width:100%;height:480px"></div>
<script src="https://api.loci.ng/embed/loci-map.js"
        data-loci-key="loci_sk_…"></script>
```

Optional attributes: `data-loci-org`, `data-loci-project`, `data-target` (selector, default `#loci-map`), `data-basemap` (`dark` | `light` | `satellite` | `streets` | `3d`), `data-center="lng,lat"`, `data-zoom`, `data-title`, `data-subtitle`, `data-mapbox-token`, `data-analysis` and `data-physical` (dataset ids for analysis and travel time). `window.LociMap.create(target, options)` is also exposed for wiring it up by hand.

> [!NOTE]
>
> The embed delivers exports as a cancelable `loci:export` CustomEvent on the
> mount element. Call `event.preventDefault()` to take the export yourself, or
> let it fall through to a file download. See
> [Export and restore](https://docs.loci.ng/sdks/web-maps.md#export-and-restore).

## What the key controls

Every dataset the sidebar lists, every feature read, and every analysis runs through the key you pass — the server filters by the key's dataset scope and capabilities, and metered reads are charged to it. A map state exported from the SDK references datasets **by id only**: contents reload through the API on restore, so your data licensing travels with the key, never with the file.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.