<Callout>

**Note:** Please reach out to us for any feedback and/or issues [here](https://github.com/aws-amplify/amplify-js/issues)

</Callout>

## Display a map

First, ensure you've provisioned an Amazon Location Service Map resource and configured your app using the instructions in either [Amplify CLI - Geo - Maps](/cli/geo/maps) or [Use existing resources](/lib/geo/existing-resources) guide.

<Callout>

**Note:** For React, you can use the [Amplify React MapView component](https://ui.docs.amplify.aws/react/components/geo)

</Callout>

To render a map, the [MapLibre GL](https://github.com/maplibre/maplibre-gl-js) and the `maplibre-gl-js-amplify` libraries are required. MapLibre GL is an open source map rendering library and `maplibre-gl-js-amplify` library makes it easy to integrate MapLibre with Amplify Geo and handles Authentication.

Add the dependencies to your app:

```bash
npm install maplibre-gl maplibre-gl-js-amplify
```

<Callout>

Verify the following:
- `maplibre-gl-js-amplify` version `2.0.0` or above is installed
- Any package bundlers (webpack, rollup, etc) are configured to handle css files. Check out the webpack documentation [here](https://webpack.js.org/loaders/css-loader/).

</Callout>

Import the library into your application:

```javascript
import { createMap } from "maplibre-gl-js-amplify";
import "maplibre-gl/dist/maplibre-gl.css";
```

Next, create and render the [Map](https://maplibre.org/maplibre-gl-js-docs/api/map/) with the help of [createMap](https://github.com/aws-amplify/maplibre-gl-js-amplify/blob/main/API.md#createmap).


**Note:** There must be a `div` with an `id="map"` on the DOM before making the call to `createMap` in this way.

```javascript
async function initializeMap() {
    const map = await createMap({
        container: "map", // An HTML Element or HTML element ID to render the map in https://maplibre.org/maplibre-gl-js-docs/api/map/
        center: [-123.1187, 49.2819], // [Longitude, Latitude]
        zoom: 11,
    })
}

initializeMap();
```

To render a map using a className or something other than the ID you can pass in a reference to the HTML Element itself.

```javascript
const element = document.getElementsByClassName("class")[0];

const map = await createMap({
    container: element,
    ...
})
```

<Callout>

The MapLibre canvas requires a defined height to display properly, otherwise you may end up with a blank screen where the map is supposed to be.

The [amplify-map.css](https://github.com/aws-amplify/maplibre-gl-js-amplify/blob/main/src/public/amplify-map.css) file has a few commonly used methods for setting the height of the map component.
You can add some of the examples listed to your own styles or directly import `amplify-map.css` like so:
```
import "maplibre-gl-js-amplify/dist/public/amplify-map.css";
```

To render a map using percentage based height you need to ensure that all ancestor elements to the map container have a height:

```css
html,
body,
#root { /* The ancestors of the map element */
  height: 100%;
}

#map {
  height: 50%;
}
```
</Callout>

![A map centered on Vancouver](/images/display-map.png)

## Display markers on map

To display markers on a map, use the `drawPoints` function. `drawPoints` expects:

- `sourceName` - specifies the layer on which the markers are rendered on. You can edit existing markers by passing the same `sourceName`
- coordinate data - (longitude, latitude) the coordinate data of the markers to be displayed
- a maplibre-gl-js Map - the map object on which to render the markers

First, import the `drawPoints` method in your app. Your import section should include look like this

```javascript
import { drawPoints } from "maplibre-gl-js-amplify";
```

<Callout>

The `drawPoints` method returns ids of the source and layers used to display the markers on the map. These ids can be used for further customization through maplibre-gl-js [source](https://maplibre.org/maplibre-gl-js-docs/api/sources/), [paint](https://maplibre.org/maplibre-gl-js-docs/style-spec/layers/#paint-property), and [layer](https://maplibre.org/maplibre-gl-js-docs/style-spec/layers/) options.

For more information about the parameters and options that can be used with `drawPoints` check the documentation [here](https://github.com/aws-amplify/maplibre-gl-js-amplify/blob/main/API.md#drawpoints).

</Callout>

Next, use the following code snippet when you want to display the markers on the map. Add it to the `initializeMap()` function if you want the markers to show up on map load.

```javascript
map.on("load", function () {
    drawPoints("mySourceName", // Arbitrary source name
        [
            {
              coordinates: [-122.483696, 37.833818], // [Longitude, Latitude]
              title: "Golden Gate Bridge",
              address: "A suspension bridge spanning the Golden Gate",
            },
            {
              coordinates: [- 122.4770, 37.8105], // [Longitude, Latitude]
            },
        ], // An array of coordinate data, an array of Feature data, or an array of [NamedLocations](https://github.com/aws-amplify/maplibre-gl-js-amplify/blob/main/src/types.ts#L8)
        map,
        {
            showCluster: true,
            unclusteredOptions: {
                showMarkerPopup: true,
            },
            clusterOptions: {
                showCount: true,
            },
        }
    );
});

```
![A map with points](/images/display-map-with-points.png)

## Display different map styles

The `getAvailableMaps` API fetches information for all maps that are available to be displayed.

This is useful if you would like to give your users a variety of maps styles to choose from.

```javascript
import { Geo } from "aws-amplify"

Geo.getAvailableMaps();
```

The available maps are returned as an array with the following contents:

```javascript
//returns
[
  {
    mapName: 'myAmplifyGeoEsriStreetMap',
    style: 'VectorEsriStreets'
  },
  {
    mapName: 'myAmplifyGeoEsriTopographicMap',
    style: 'VectorEsriTopographic'
  },
]
```

You can resize and customize a map with the `resize` and `setStyle` functions:

```javascript
map.setStyle("myAmplifyGeoEsriTopographicMap"); // map name received from getAvailableMaps()
map.resize(); // forces the map to re-render
```

## Removing a map from the DOM

When it's time to remove the map from the DOM, you can use the `.remove` method of the generated map. This will clean up and release all resources associated with the map (DOM elements, event bindings, web workers, and WebGL resources).

```javascript
map.remove();
```

<Callout warning>

After calling `.remove()`, you must not call any other methods on the map.

</Callout>

<Callout warning>

**For React users:**

Not removing the map on component unmount can cause memory leaks in your application. It's recommended to call `.remove()` in either the return function of a React `useEffect` hook or the `componentWillUnmount` lifecycle hook of a class component.

</Callout>

## Add map to html website

To display a map on your html website, add the following scripts to your html webpage.

```html
<link href="https://cdn.amplify.aws/packages/maplibre-gl/1.15.2/maplibre-gl.css" rel="stylesheet" integrity="sha384-DrPVD9GufrxGb7kWwRv0CywpXTmfvbKOZ5i5pN7urmIThew0zXKTME+gutUgtpeD" crossorigin="anonymous" referrerpolicy="no-referrer"></link>
<script src="https://cdn.amplify.aws/packages/maplibre-gl/1.15.2/maplibre-gl.js" integrity="sha384-rwYfkmAOpciZS2bDuwZ/Xa/Gog6jXem8D/whm3wnsZSVFemDDlprcUXHnDDUcrNU" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdn.amplify.aws/packages/core/4.3.0/aws-amplify-core.min.js" integrity="sha384-7Oh+5w0l7XGyYvSqbKi2Q7SA5K640V5nyW2/LEbevDQEV1HMJqJLA1A00z2hu8fJ" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdn.amplify.aws/packages/auth/4.3.8/aws-amplify-auth.min.js" integrity="sha384-jfkXCEfYyVmDXYKlgWNwv54xRaZgk14m7sjeb2jLVBtUXCD2p+WU8YZ2mPZ9Xbdw" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdn.amplify.aws/packages/geo/1.1.0/aws-amplify-geo.min.js" integrity="sha384-TFMTyWuCbiptXTzvOgzJbV8TPUupG1rA1AVrznAhCSpXTIdGw82bGd8RTk5rr3nP" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdn.amplify.aws/packages/maplibre-gl-js-amplify/1.1.0/maplibre-gl-js-amplify.umd.min.js" integrity="sha384-7/RxWonKW1nM9zCKiwU9x6bkQTjldosg0D1vZYm0Zj+K/vUSnA3sOMhlRRWAtHPi" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
```

Next, add a div element with id `map` anywhere in your webpage where you want to render the map. Include the following code snippet to configure Amplify (update the `aws_exports.js` file path accordingly) and instantiate the map.

```html
<script type="module">
    import awsconfig from "./aws-exports.js";
    const { Amplify } = aws_amplify_core;
    const { createMap } = AmplifyMapLibre;
    Amplify.configure(awsconfig);
    createMap({
        container: "map",
        center: [-123.1187, 49.2819], // [Longitude, Latitude]
        zoom: 13,
    });
</script>
```

<!-- If you provisioned your location resources manually, you can use this [guide]() to configure Amplify.-->
### Sample application
```html
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>Display a map on a webpage</title>
        <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no">
        <link href="https://cdn.amplify.aws/packages/maplibre-gl/1.15.2/maplibre-gl.css" rel="stylesheet" integrity="sha384-DrPVD9GufrxGb7kWwRv0CywpXTmfvbKOZ5i5pN7urmIThew0zXKTME+gutUgtpeD" crossorigin="anonymous" referrerpolicy="no-referrer"></link>
        <script src="https://cdn.amplify.aws/packages/maplibre-gl/1.15.2/maplibre-gl.js" integrity="sha384-rwYfkmAOpciZS2bDuwZ/Xa/Gog6jXem8D/whm3wnsZSVFemDDlprcUXHnDDUcrNU" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
        <script src="https://cdn.amplify.aws/packages/core/5.0.5/aws-amplify-core.min.js" integrity="sha384-eM2urkpomL9SRm/kuPHZG3XPEItAiUAAyotT/AqlhSus8iAqs/EfHaYy1Jn5ih7K" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
        <script src="https://cdn.amplify.aws/packages/auth/5.0.5/aws-amplify-auth.min.js" integrity="sha384-H25CFLYd7YHa1Oib73fs3kJN36VhaHHkLjo4AhGrhJ4HuKam05pg2/0t2MR6epun" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
        <script src="https://cdn.amplify.aws/packages/geo/2.0.5/aws-amplify-geo.min.js" integrity="sha384-Esc9xx0X7ckb/yeYHuYsZGqBB4FwYr98NFHS3BRXLeRE/eB0uVrad2w+G6cGxYb5" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
        <script src="https://cdn.amplify.aws/packages/maplibre-gl-js-amplify/1.5.0/maplibre-gl-js-amplify.umd.min.js" integrity="sha384-9kJyZavd3Jk6QzHeaLpugVonfZmZZZdixek6uglOwzKtZvDS9K3W4dshw1uswmlV" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
        <style>
            body { margin: 0; padding: 0; }
            #map { position: absolute; top: 0; bottom: 0; width: 100%; }
        </style>
    </head>
    <body>
        <div id="map"></div>
        <script type="module">
            import awsconfig from "./aws-exports.js";
            const { Amplify } = aws_amplify_core;
            const { createMap } = AmplifyMapLibre;
            Amplify.configure(awsconfig);
            createMap({
                container: "map",
                center: [-123.1187, 49.2819], // [Longitude, Latitude]
                zoom: 13,
            });
        </script>
    </body>
</html>
```

## Map API's

If you want more information about the maps you currently have configured or want a way to switch between maps programmatically, the `@aws-amplify/geo` package provides API's that return more information about your currently provisioned maps.

First, you need to import Geo from either the `@aws-amplify/geo` or `aws-amplify` packages.

```javascript
import { Geo } from "@aws-amplify/geo";
// Or
import { Geo } from "aws-amplify";
```

### getAvailableMaps

`getAvailableMaps` will return the map resources you currently have provisioned in your Amplify project. You can switch between any of these different maps and display their different map styles.

#### API

```javascript
Geo.getAvailableMaps() => Promise<AmazonLocationServiceMapStyle[]>;
```

#### Parameters

- N/A

#### Return

The return from `getAvailableMaps` is a Promise that resolves to `AmazonLocationServiceMapStyle[]` which is an array of `mapName`, `style`, and `region`.

Each object has the following properties:

- `mapName` - name of the map you created.
- `style` - the Amazon Location Service style used to create the map.
- `region` - the AWS region the map is hosted in.

<Callout>

**Note:** When changing a map with Amplify and MapLibre the [setStyle](https://maplibre.org/maplibre-gl-js-docs/api/map/#map#setstyle) function should be called with the name of the Location Service map NOT the style. This is because the `transformRequest` function uses the Location Service map name to make a new request for map tile data.

</Callout>

#### Example

```js
const availableMaps = await Geo.getAvailableMaps();

map.setStyle(availableMaps[0].mapName);
```

### getDefaultMap

`getDefaultMap` is used to get a the default map object.

#### API

```javascript
Geo.getDefaultMap() => Promise<AmazonLocationServiceMapStyle>;
```

#### Parameters

- N/A

#### Return

The return from `getDefaultMap` is a Promise that resolves to a AmazonLocationServiceMapStyle object.

The object has the following properties:

- `mapName` - name of the map you created.
- `style` - the Amazon Location Service style used to create the map.
- `region` - the AWS region the map is hosted in.

#### Example

```javascript
const defaultMap = await Geo.getDefaultMap();
```
