> For the complete documentation index, see [llms.txt](https://docs.mapbox.com/help/ja/llms.txt)

# Use Mapbox GL JS in a Svelte app

**Svelte** is a popular JavaScript web framework used for increasing client performance. Since Svelte manipulates the DOM, it can be confusing to connect Svelte with other libraries that also manipulate the DOM and manage state — like Mapbox GL JS.

In this tutorial, you will learn how to create a Svelte web app that uses Mapbox GL JS to render a map, dynamically display the coordinates of the map center point and its zoom level when a user interacts with the map and be able to reset the map view with an UI element.

This tutorial shows code for Svelte [Bindings](https://svelte.dev/tutorial/svelte/bind-this) and [Component Lifecycles](https://svelte.dev/docs/svelte/lifecycle-hooks).

If you'd like to get a Svelte app running with **Mapbox GL JS** and are not interested in the additional learning of this tutorial use the Mapbox `npm create @mapbox/web-app` utility, choose Svelte as your framework and scaffold your application in seconds.

```
$ npm create @mapbox/web-app
```

## Prerequisites

You will need a few things in place before starting this tutorial:

-   **A Mapbox access token**: Find yours on the [Access token page](https://console.mapbox.com/account/access-tokens/) of your Developer Console.
-   [**Mapbox GL JS**](https://docs.mapbox.com/mapbox-gl-js/): is a JavaScript library for building web maps and applications with Mapbox.- **A Code editor**: A program like [Visual Studio Code](https://code.visualstudio.com/). **Node.js and npm.** [Download and install](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm) the latest version.
-   **Familiarity with Svelte development.** Beginner experience with Svelte and JavaScript.

## Create a Svelte app with Vite

To get started, we'll use [Vite JS](https://vite.dev) to quickly scaffold a Svelte project. This will create a base layer to build our Svelte app upon. Wherever you want the folder for this project to exist on your computer, navigate to that directory via the command line and run the following command:

```sh
$ npm create vite@latest use-mapbox-gl-js-with-svelte -- --template svelte
```

Follow the instructions to change directories, install dependencies (`npm install`) run the development server (`npm run dev`).

```sh
$ npm run dev

> use-mapbox-gl-js-with-svelte@0.0.0 dev
> vite

Forced re-optimization of dependencies

  VITE v6.0.7  ready in 566 ms

  ➜  Local:   http://localhost:5173/
  ➜  Network: use --host to expose
  ➜  press h + enter to show help
```

Load the provided URL (`http://localhost:5173/`) in your browser and you should see the development server running.

![Svelte Dev Server](https://docs.mapbox.com/help/ja/assets/ideal-img/tutorials--use-mapbox-gl-js-with-svelte--dev-server.bddd6fe.480.png)

Next you need to install Mapbox GL JS in this project. Run the following command:

```sh
$ npm install mapbox-gl
```

Open the project you've created, navigate to the `src/app.css` file. This contains the CSS styles to create the page we saw above. We don't need any of these styles in our app, so delete all existing CSS and add the snippet below.

```css
body {
  margin: 0;
  padding: 0;
}
```

## Create the map container & add the map

Following Svelte patterns, all the following code (including HTML, CSS, and JavaScript) will occur in the `src/App.svelte` file. Open this file.

This app will include a Mapbox map, JavaScript to handle storing and updating information about the map, a sidebar `<div>` to show that information, and CSS to style the `<div>`. You should set up the bones of your app like this; we will handle the map itself later. Delete any HTML in `App.svelte` and replace it with the following:

```html
<script></script>

<!-- Your HTML will go here  -->

<style></style>
```

### Add Mapbox GL JS

Add the following `import` statements between your `<script>` tags to import the Map object from Mapbox GL and Mapbox GL's CSS to your Svelte app:

```js
<script>
import { Map } from 'mapbox-gl';
import 'mapbox-gl/dist/mapbox-gl.css';
</script>

<style></style>
```

### Add variables

To load a map on a webpage with Svelte, we need to create variables for the map, the HTML element that will contain the map, and the map's starting position (including longitude, latitude, and zoom level).

Add the following between your `<script>` tags, below your `import` statements:

```js
<script>
import { Map } from 'mapbox-gl';
import 'mapbox-gl/dist/mapbox-gl.css';

let map;
let mapContainer;
let lng, lat, zoom;

lng = -71.224518;
lat = 42.213995;
zoom = 9;

let initialState = { lng, lat, zoom };
</script>

<style></style>
```

These positional values will create a map centered near Boston, Massachusetts.

### Use Svelte binding

The Mapbox `map` needs certain attributes defined immediately to work, such as the map's `center` and `container`. This container is an `<div>` that the map renders in.

To do this, we will use Svelte binding. Insert this HTML between your script & style tags.

```js
<script>
  import { Map } from 'mapbox-gl';
  import 'mapbox-gl/dist/mapbox-gl.css';

  let map;
  let mapContainer;
  let lng, lat, zoom;

  lng = -71.224518;
  lat = 42.213995;
  zoom = 9;

  let initialState = { lng, lat, zoom };
</script>

<div class="map" bind:this={mapContainer} /> 

<style></style>
```

This "binds" the variable `mapContainer` to the `<div>` with class "map". Once we instantiate the map (in the next step) and reference the `mapContainer` then when the page is rendered the map will be loaded into this `div`.

### Add map CSS

Now that there exists an HTML element with a class of `map`, we can apply CSS styling to that class. Between your empty `<style>` tags, add the following:

```js
<script>
  import { Map } from 'mapbox-gl';
  import 'mapbox-gl/dist/mapbox-gl.css';

  let map;
  let mapContainer;
  let lng, lat, zoom;

  lng = -71.224518;
  lat = 42.213995;
  zoom = 9;

  let initialState = { lng, lat, zoom };
</script>

<div class="map" bind:this={mapContainer} /> 

<style>
  .map {
    position: absolute;
    width: 100%;
    height: 100%;
  }
</style>
```

### Add Svelte lifecycle

You will import Svelte functions right below where you imported the `Map` object from Mapbox GL. On the next line, add:

```js
<script>
  import { Map } from 'mapbox-gl';
  import 'mapbox-gl/dist/mapbox-gl.css';
  // highlight-start
  import { onMount, onDestroy } from 'svelte';
  // highlight-end 

    let map;
    let mapContainer;
    let lng, lat, zoom;
  ...
```

`onMount` and `onDestroy` are Svelte lifecycle functions. `onMount` in particular runs after a component is first rendered to the DOM. The creation of the map should go in `onMount`.

Add the following directly underneath your variable declarations and definitions. **Note**: YOUR_MAPBOX_ACCESS_TOKEN is required here. Log in to [console.mapbox.com](https://console.mapbox.com) if it is not already present in the snippet below.

```js
<script>
  import { Map } from 'mapbox-gl';
  import 'mapbox-gl/dist/mapbox-gl.css';
  import { onMount, onDestroy } from 'svelte';

  let map;
  let mapContainer;
  let lng, lat, zoom;

  lng = -71.224518;
  lat = 42.213995;
  zoom = 9;

  let initialState = { lng, lat, zoom };

  onMount(() => {
    map = new Map({
      container: mapContainer,
      accessToken: "YOUR_MAPBOX_ACCESS_TOKEN",
      center: [initialState.lng, initialState.lat],
      zoom: initialState.zoom
    });
  });

  onDestroy(() => {
    map.remove();
  });

</script>

<div class="map" bind:this={mapContainer} /> 

<style>
  .map {
    position: absolute;
    width: 100%;
    height: 100%;
  }
</style>
```

At this point, you've added enough code to load a Mapbox map in a Svelte app. Run `npm run dev` in your app's root directory to launch the development server, and you should see an interactive map of Boston.

## Respond to map interactions

This app will respond to events generated by user interactions and will be able to store and render the longitude, latitude, and zoom for the map in a UI element. These values will all change as your user interacts with the map, and the UI will update with it.

### Add UI HTML

As we've already created these variables (`lng`, `lat`, and `zoom`), it's time to add to the `<div>` that will become the informational sidebar UI element. Add the following HTML into your app, below the `<div>` with class "map".

```js
...
  </script>

  <div class="map" bind:this={mapContainer} /> 

// highlight-start
  <div class="sidebar">
    Longitude: {lng.toFixed(4)} | Latitude: {lat.toFixed(4)} | Zoom:
    {zoom.toFixed(2)}
  </div>
  // highlight-end

  <style>
...
```

### Add sidebar CSS

If you run `npm run dev` at this point, you will see that the map's initial position and zoom are displayed above the map; The presentation is not styled and does not change when interacting with the map.

We should style the display. Between your `<style>` tags, under the rules for the `map` class, add the following:

```css
...

  <style>
    .map {
      position: absolute;
      width: 100%;
      height: 100%;
    }
    // highlight-start
    .sidebar {
      background-color: rgb(35 55 75 / 90%);
      color: #fff;
      padding: 6px 12px;
      font-family: monospace;
      z-index: 1;
      position: absolute;
      top: 0;
      left: 0;
      margin: 12px;
      border-radius: 4px;
    }
    // highlight-end
  </style>
```

**Note:** at this moment the numbers in our Sidebar UI are static as we haven't yet responded to user interactions.

### Update center and zoom information

Next, you need to create a function that stores the new latitude, longitude, and zoom that you get when a user interacts with the map. We'll use a [`map.on()`](https://docs.mapbox.com/mapbox-gl-js/api/map/#map#on) function with a `'move'` event inside the `onMount()` to reset the value of these variables when a user moves the map. Add the `updateData()` function and `map.on` function as seen below.

```js
<script>
  import { Map } from 'mapbox-gl';
  import 'mapbox-gl/dist/mapbox-gl.css';
  import { onMount, onDestroy } from 'svelte';

  let map;
  let mapContainer;
  let lng, lat, zoom;

  lng = -71.224518;
  lat = 42.213995;
  zoom = 9;

  let initialState = { lng, lat, zoom };

  function updateData() {
    zoom = map.getZoom();
    lng = map.getCenter().lng;
    lat = map.getCenter().lat;
  }

  onMount(() => {
    map = new Map({
      container: mapContainer,
      accessToken: "YOUR_MAPBOX_ACCESS_TOKEN",
      center: [initialState.lng, initialState.lat],
      zoom: initialState.zoom
    });

    map.on('move', () => {
      updateData();
    });
  });

  onDestroy(() => {
    map.remove();
  });

</script>

<div class="map" bind:this={mapContainer} /> 

<div class="sidebar">
  Longitude: {lng.toFixed(4)} | Latitude: {lat.toFixed(4)} | Zoom:
  {zoom.toFixed(2)}
</div>

<style>
  .map {
    position: absolute;
    width: 100%;
    height: 100%;
  }

  .sidebar {
    background-color: rgb(35 55 75 / 90%);
    color: #fff;
    padding: 6px 12px;
    font-family: monospace;
    z-index: 1;
    position: absolute;
    top: 0;
    left: 0;
    margin: 12px;
    border-radius: 4px;
  }
</style>
```

## Control the map with external events

As a last step to show manipulating the map from our Svelte app, we will add a reset button that resets the map view to the initial view state.

### Add HTML & CSS

Add this `<button>` HTML below your sidebar `<div>` and the following CSS into your `<style>` tags.

```js
<script>
  import { Map } from 'mapbox-gl';
  import 'mapbox-gl/dist/mapbox-gl.css';
  import { onMount, onDestroy } from 'svelte';

  let map;
  let mapContainer;
  let lng, lat, zoom;

  lng = -71.224518;
  lat = 42.213995;
  zoom = 9;

  let initialState = { lng, lat, zoom };

  function updateData() {
    zoom = map.getZoom();
    lng = map.getCenter().lng;
    lat = map.getCenter().lat;
  }

  onMount(() => {
    map = new Map({
      container: mapContainer,
      accessToken: "YOUR_MAPBOX_ACCESS_TOKEN",
      center: [initialState.lng, initialState.lat],
      zoom: initialState.zoom
    });

    map.on('move', () => {
      updateData();
    });
  });

  onDestroy(() => {
    map.remove();
  });

</script>

<div class="map" bind:this={mapContainer} /> 

<div class="sidebar">
  Longitude: {lng.toFixed(4)} | Latitude: {lat.toFixed(4)} | Zoom:
  {zoom.toFixed(2)}
</div>

<button onclick={handleReset} class="reset-button">Reset</button>

<style>
  .map {
    position: absolute;
    width: 100%;
    height: 100%;
  }

  .sidebar {
    background-color: rgb(35 55 75 / 90%);
    color: #fff;
    padding: 6px 12px;
    font-family: monospace;
    z-index: 1;
    position: absolute;
    top: 0;
    left: 0;
    margin: 12px;
    border-radius: 4px;
  }

  .reset-button {
    position: absolute;
    top: 50px;
    z-index: 1;
    left: 12px;
    padding: 4px 10px;
    border-radius: 10px;
    cursor: pointer;
  }
</style>
```

### Add click handler

Lastly we'll add our `handleReset` function into our `<script>` tag below our `onDestroy()` callback.

```js
...
onDestroy(() => {
      map.remove();
});

// highlight-start
function handleReset() {
    map.flyTo({
      center: [initialState.lng, initialState.lat],
      zoom: initialState.zoom,
      essential: true
    });
  }
// highlight-end
</script>
...
```

This function uses the [`flyTo`](https://docs.mapbox.com/mapbox-gl-js/api/map/#map#flyto) method to animate the camera object to the initial view, using the initial center coordinates & zoom.

> **Related content (playground): [Location Helper](https://labs.mapbox.com/location-helper/#3/40.78/-73.97)**
> 
> To experiment with camera pitch, bearing, tilt, and zoom and get values to use in your code, try our *Location Helper* tool.

## Final product

The final `App.svelte` page will look like the following:

```html
<script>
  import { Map } from 'mapbox-gl';
  import { onMount, onDestroy } from 'svelte';
  import 'mapbox-gl/dist/mapbox-gl.css';

  let map;
  let mapContainer;
  let lng, lat, zoom;

  lng = -71.224518;
  lat = 42.213995;
  zoom = 9;

  let initialState = { lng, lat, zoom };

  function updateData() {
    zoom = map.getZoom();
    lng = map.getCenter().lng;
    lat = map.getCenter().lat;
  }

  onMount(() => {

    map = new Map({
      container: mapContainer,
      accessToken: "YOUR_MAPBOX_ACCESS_TOKEN",
      center: [initialState.lng, initialState.lat],
      zoom: initialState.zoom
    });

    map.on('move', () => {
      updateData();
    });
  });

  onDestroy(() => {
      map.remove();
  });

  function handleReset() {
    map.flyTo({
      center: [initialState.lng, initialState.lat],
      zoom: initialState.zoom,
      essential: true
    });
  }
</script>

<div class="map" bind:this={mapContainer}></div>
<div class="sidebar">
  Longitude: {lng.toFixed(4)} | Latitude: {lat.toFixed(4)} | Zoom:
  {zoom.toFixed(2)}
</div>
<button onclick={handleReset} class="reset-button">Reset</button>


<style>
  .map {
    position: absolute;
    width: 100%;
    height: 100%;
  }

  .sidebar {
    background-color: rgb(35 55 75 / 90%);
    color: #fff;
    padding: 6px 12px;
    font-family: monospace;
    z-index: 1;
    position: absolute;
    top: 0;
    left: 0;
    margin: 12px;
    border-radius: 4px;
  }

  .reset-button {
    position: absolute;
    top: 50px;
    z-index: 1;
    left: 12px;
    padding: 4px 10px;
    border-radius: 10px;
    cursor: pointer;
  }
</style>
```

## Next steps

**Congratulations!** You have created a [Svelte](https://svelte.dev/) app that uses [Mapbox GL JS](https://docs.mapbox.com/mapbox-gl-js/) to render a map, display the center coordinates and the zoom level of the map, and then update that display when a user interacts with the map.

### What we covered

-   Creating a [Svelte](https://svelte.dev/) App with [Vite JS](https://vite.dev)
-   Importing [Mapbox GL JS](https://docs.mapbox.com/mapbox-gl-js/) into your app
-   Rendering a Map
-   Displaying a Sidebar with Map data that updates dynamically
-   Resetting a map's view

Now that you have created a Svelte app that uses Mapbox GL JS, explore more functionality of GL JS in [examples](https://docs.mapbox.com/mapbox-gl-js/example/), or learn about [Mapbox Studio](https://docs.mapbox.com/studio-manual/) and how you can create custom map styles and upload your own map datasets.