# Bootstrap 5 Vector Map

Bootstrap 5 vector map with jsVectorMap in AdminKit: a world map with markers in theme colors that follows dark mode, plus a US map in AdminKit PRO.

Use a vector map to show where things happen: your offices, your customers or where your visitors come from. It draws an interactive SVG map with markers. People can zoom in, drag the map around and hover a marker to see its name.

AdminKit uses [jsVectorMap](https://github.com/themustafaomar/jsvectormap) 1.7.0 in the free and PRO versions. The free version has the world map. AdminKit PRO adds a map of the United States.

The map takes its colors from the current color mode. You describe the map in a function that receives the theme colors, and AdminKit calls it again when someone switches between light and dark mode. [Dark mode](/bootstrap/docs/getting-started/dark-mode/#charts-and-maps) explains the theme colors and the other helpers that work this way.

## Example

A world map with markers, as on the Analytics dashboard. Hover a marker to see the city.

```html
<div class="card mb-0">
  <div class="card-header">
    <h2 class="card-title mb-0">Real-Time Visitors</h2>
  </div>
  <div class="card-body px-4" aria-busy="true">
    <div class="position-relative" style="height: 350px;">
      <div class="skeleton placeholder-glow" aria-hidden="true"><span class="placeholder"></span></div>
      <div id="world_map" class="h-100"></div>
    </div>
  </div>
</div>

<script>
var map = adminkit.vectorMap(function (theme) {
  return {
    selector: "#world_map",
    map: "world",
    zoomButtons: true,
    zoomOnScroll: false,
    markers: [
      { coords: [31.230391, 121.473701], name: "Shanghai" },
      { coords: [28.70406, 77.102493], name: "Delhi" },
      { coords: [6.524379, 3.379206], name: "Lagos" },
      { coords: [35.689487, 139.691711], name: "Tokyo" },
      { coords: [40.7127837, -74.0059413], name: "New York" },
      { coords: [34.052235, -118.243683], name: "Los Angeles" },
      { coords: [51.507351, -0.127758], name: "London" },
      { coords: [40.416775, -3.70379], name: "Madrid" }
    ],
    markerStyle: {
      initial: { r: 9, stroke: theme.white, strokeWidth: 7, fill: theme.primary },
      hover: { fill: theme.primary, stroke: theme.primary }
    },
    regionStyle: {
      initial: { fill: theme["gray-200"] }
    }
  };
});

window.addEventListener("resize", function () {
  map.updateSize();
});
</script>
```

The map fills its element, so that element needs a height. Here it is the `h-100` child of a `position-relative` box of 350px. The same box holds the loading skeleton, so nothing moves when the map appears. [Animations](/bootstrap/docs/getting-started/animations/#skeletons) explains the skeleton markup.

## Use it in your page

`js/app.js` loads jsVectorMap and its maps, and adds `adminkit.vectorMap()` to the page. There is nothing else to install.

`app.js` is a module script, so it runs after the page has been parsed. The template's pages therefore create their maps in a `DOMContentLoaded` listener, which runs after `app.js`:

```html
<div id="world_map" style="height: 350px;"></div>

<script>
  document.addEventListener("DOMContentLoaded", function () {
    var map = adminkit.vectorMap(function (theme) {
      return {
        selector: "#world_map",
        map: "world",
        zoomButtons: true,
        zoomOnScroll: false,
        markers: [
          { coords: [51.507351, -0.127758], name: "London" },
          { coords: [40.7127837, -74.0059413], name: "New York" }
        ],
        markerStyle: {
          initial: { r: 9, stroke: theme.white, strokeWidth: 7, fill: theme.primary },
          hover: { fill: theme.primary, stroke: theme.primary }
        },
        regionStyle: {
          initial: { fill: theme["gray-200"] }
        }
      };
    });

    window.addEventListener("resize", function () {
      map.updateSize();
    });
  });
</script>
```

`adminkit.vectorMap()` returns the jsVectorMap instance. When the map has drawn, it removes the skeleton in the closest `aria-busy="true"` element and sets `aria-busy="false"`.

jsVectorMap does not follow the size of its element by itself. That is why the template calls `map.updateSize()` when the window is resized. Call it too after you show a map that was hidden, for example in a tab or a modal.

## Options

The function returns [jsVectorMap's options](https://github.com/themustafaomar/jsvectormap). These are the ones the template sets:

| Option | Template value | What it does |
| --- | --- | --- |
| `selector` | `"#world_map"` | The element to draw the map in |
| `map` | `"world"` | The map to draw: `"world"`, or `"us_aea_en"` in AdminKit PRO |
| `zoomButtons` | `true` | Shows the + and − buttons |
| `zoomOnScroll` | `false` | Leaves the mouse wheel to the page, so it scrolls past the map |
| `markers` | `[{ coords: [lat, lng], name }]` | The points to mark, with the name shown on hover |
| `markerStyle` | `initial` and `hover` | The markers' radius, fill and stroke |
| `regionStyle` | `initial` | The fill of the countries or states |

## Colors and dark mode

The function gets the colors of the current mode, such as `theme.primary`, `theme.white` and `theme["gray-200"]`. In dark mode, `theme.white` is the card background, so the white ring around each marker blends in with the card in both modes.

When the mode changes, AdminKit calls your function again with the new colors. It applies the new `regionStyle.initial` and `markerStyle.initial` to the map. The map is not created again, so the other options, such as `markers`, are only read once.

In AdminKit PRO, the zoom buttons also get a background color of their own in light and in dark mode. In the free version they keep jsVectorMap's own colors.

## United States map

> This map is only available in **AdminKit PRO**. [Learn more](/pricing/#bootstrap).

When your data is about the US, show the states instead of the world. `map: "us_aea_en"` draws them in an Albers equal-area projection. The E-commerce dashboard uses it for sales by state:

```html
<div class="position-relative" style="height: 350px;">
  <div id="usa_map" class="h-100"></div>
</div>

<script>
var usaMap = adminkit.vectorMap(function (theme) {
  return {
    selector: "#usa_map",
    map: "us_aea_en",
    zoomButtons: true,
    zoomOnScroll: false,
    markers: [
      { coords: [37.77, -122.41], name: "San Francisco: 375" },
      { coords: [40.71, -74.0], name: "New York: 350" },
      { coords: [39.09, -94.57], name: "Kansas City: 250" },
      { coords: [36.16, -115.13], name: "Las Vegas: 275" },
      { coords: [32.77, -96.79], name: "Dallas: 225" }
    ],
    markerStyle: {
      initial: { r: 9, stroke: theme.white, strokeWidth: 7, fill: theme.primary },
      hover: { fill: theme.primary, stroke: theme.primary }
    },
    regionStyle: {
      initial: { fill: theme["gray-200"] }
    }
  };
});

window.addEventListener("resize", function () {
  usaMap.updateSize();
});
</script>
```

## Other maps

The build includes only the maps above. Each map is a JavaScript file that registers itself with `jsVectorMap.addMap()`. The files are in `src/js/modules/vector-maps/`, and `src/js/modules/vector-maps.js` imports the ones the build includes.

AdminKit PRO has more map files in that folder that the build leaves out: `canada`, `iraq`, `russia`, `spain`, `us_lcc_en`, `us_merc_en`, `us_mill_en` and `world_merc`. To use one, import its file in `vector-maps.js`, next to the world map, and build again:

```js
import "./vector-maps/world.js";
import "./vector-maps/us-aea-en.js";
import "./vector-maps/canada.js";
```

Then pass the registered name as `map`, for example `map: "canada"`. Each import makes `js/app.js` larger, so add only the maps you show.

## Accessibility

- The map is an SVG drawing without a text alternative. Give the same information as text as well, such as a list or a table of the markers.
- Keep `zoomOnScroll: false`, as the template does. Otherwise the map catches the mouse wheel and the page stops scrolling under the pointer.
- The marker names only show on hover. Do not put information there that the page does not give elsewhere.

## Related

- [React Vector Map](/react/docs/plugins/vector-map/): the `VectorMap` component in AdminKit for React
- [Next.js Vector Map](/nextjs/docs/plugins/vector-map/): the same component in AdminKit for Next.js
- [Dark mode](/bootstrap/docs/getting-started/dark-mode/#charts-and-maps): the theme colors and `adminkit.vectorMap()` next to the chart helpers
- [Animations](/bootstrap/docs/getting-started/animations/#skeletons): the skeleton that shows until the map has drawn
- [Card](/bootstrap/docs/components/card/): the card around the map
- [Vector maps demo](https://demo.adminkit.io/maps-vector.html)
- [Analytics dashboard demo](https://demo.adminkit.io/index.html): the world map
- [E-commerce dashboard demo](https://demo.adminkit.io/dashboard-ecommerce.html): the United States map

---

Canonical HTML page: https://adminkit.io/bootstrap/docs/plugins/vector-map/

Site overview for agents: https://adminkit.io/llms.txt (expanded: https://adminkit.io/llms-full.txt) · Documentation: https://adminkit.io/bootstrap/docs/ · Questions: support@adminkit.io
