All tutorials

Combining the what3words.js AutoSuggest Component with a Mapbox Map

intermediate

The easiest way to add what3words to your technology is to use one of the what3words components. The following tutorial will demonstrate how to integrate the what3words JavaScript component with Mapbox API.

The AutoSuggest Component allows users to quickly and correctly input a what3words address to a form input or search field by providing suggestions as a user types and validation to ensure the input value is a valid what3words address. The component by default uses the what3words API, or can be configured to use a privately hosted instance of the what3words API.

Please refer to this tutorial to get more information on how to use the what3words JavaScript AutoSuggest Component.

To access the Mapbox API, users will need to sign up for a Mapbox developer account and create an API key. If you are new to Mapbox API, start with the MapBox GL JS API documentation.

We also have tutorials demonstrating its use with both LeafletJS and Google Map.

1Get API key
2Create an HTML page

Define an HTML page to create a map that is the full width and height of the web browser window.

Add HTML and CSS to create a page with a map element. The #map is the element that displays the map and its CSS resets any browser settings, so it can take the full width and height of the browser.
The <!DOCTYPE html> tag is not required in CodeSandbox. If you are using a different editor or running the page on a local server, be sure to add this tag to the top of your HTML page.

<!DOCTYPE html>
<html lang="en">
 <head>
   <meta charset="UTF-8" />

<meta charset="utf-8" />
   <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no" />
   <title>Autosuggest Component (Mapbox)</title>
   <style>
     html,
      body,
      #map {
       position: absolute;
       height: 100%;
       width: 100%;
       margin: 0;
       padding: 0;
      }
   </style>
 </head>
 <body>
   <div id="map"></div>
 </body>
</html>
Copied
3Reference the APIs

In the <head> tag, add references to the CSS file and JS library for the Mapbox API and the JavaScript library for what3words API. The CSS file is required to display the map and make elements like Popups and Markers work.

You can also attach the what3words API to the window, which is accessible via window.what3words, and set a callback function for it, using script tags like the ones in the following example. Don’t forget to set your what3words API key.

Note: We prefer to use a fixed version for the Production version of your integrations. A specific version can also be specified within the script to ensure a predictable version of the component is loaded, for example@4.2.. A log of versions can be found here.

<head>
  ...
  // mapbox js library
  <script src='https://api.mapbox.com/mapbox-gl-js/v2.5.1/mapbox-gl.js'></script>

  // what3words js library
  <script
    type="module"
    async
    src="https://cdn.what3words.com/javascript-components@4.2.2/dist/what3words/what3words.esm.js"
  ></script>
  <script
    nomodule
    async
    src="https://cdn.what3words.com/javascript-components@4.2.2/dist/what3words/what3words.js"
  ></script>
  <script>
    // Attach the what3words API to the window accessible via window.what3words 
    // and set the callback function for it
    window.w3w={
      callback: "initW3w"
    };
  </script>

  // mapbox css file
  <link href='https://api.mapbox.com/mapbox-gl-js/v2.5.1/mapbox-gl.css' rel='stylesheet' />
...
</head>
<body>
  ...
  <script>
    function initW3w(what3words) {
      //pass your what3words API key to make calls to the what3words API
      what3words.api.setApiKey("YOUR-API-KEY");
      ...
    }
  </script>
</body>
Copied
4Loading a map using Mapbox

Now you can place the map on the page, centered at a location of your choosing. The #map in the <html> tag will render the map.

function initW3w(what3words) {
  ...
  mapboxgl.accessToken = YOUR_MAPBOX_ACCESS_TOKEN;
  const map = new mapboxgl.Map({
    container: 'map',
    style: 'mapbox://styles/mapbox/streets-v9',
    center: [-0.195499, 51.52086],
    zoom: 12
  });
  ...
}
Copied

To Display map navigation controls on the Mapbox map, use addControl to add zoom and rotation controls to the map.

const nav = new mapboxgl.NavigationControl();
map.addControl(nav, 'bottom-right');
Copied
5Position the component on the map

Determine the position of the component on the map.

html,
body,
#map {
 position: absolute;
 height: 100%;
 width: 100%;
 margin: 0;
 padding: 0;
}

#autosuggest {
  position: absolute;
  top: 10px;
  left: 10px;
  z-index: 100;
}

#wrapper {
  position: relative;
  height: 100%;
}
Copied

Tie the component to the styling. Ensure you include <div id=”map”></div> within the wrapper to display the map.

<div id="wrapper">
  ...
  <div id="map"></div>
</div>
Copied

In a few lines of code, you can have an input box that will call the what3words AutoSuggest API endpoint.

The api_key parameter contains your application’s API key. Replace YOUR-API-KEY with your what3words API key to get started.

Sign up to obtain your free API key.

<div id="wrapper">
  <what3words-autosuggest id="autosuggest" api_key="YOUR-API-KEY">
    <input type="text" />
  </what3words-autosuggest>
  <div id="map"></div>
</div>

Copied
6Listen for the select event

The code snippet below shows how to use an event listener to detect when a user selects a what3words address from the listed suggestions for their input. For debug purposes, it has been added a console log to show how to retrieve the words of the suggestions:

function initW3w(what3words) {
  ...
  let words;
  const autosuggest = document.getElementById("autosuggest");
  autosuggest.addEventListener("selected_suggestion", (value) => {
    let words = value.detail.suggestion.words;
    // console.log(words);
  });
  ...
}
Copied
7Convert what3words address to coordinates

To convert a what3words address to coordinates, users will need to call the what3words API as shown below. They will need to add this code snippet within the autosuggest event listener.

function initW3w(what3words) {
  ...
  let words;
  const autosuggest = document.getElementById("autosuggest");
  autosuggest.addEventListener("selected_suggestion", (value) => {
    let words = value.detail.suggestion.words;

    // what3words api call request
    what3words.api
    .convertToCoordinates({ words: words, format: "geojson" })
    .then(function (response) {
      console.log("[convertToCoordinates]", response);

    });
  });
}
Copied
8Place a map marker

Now that the coordinates of the 3 words address are retrieved from the above call to the what3words API, users can place a simple map marker on the map and centre the map on its location.

<script>
  function initW3w(what3words) {
	...
    // save current map markers in a list (as global variable)
    let markers = [];
    let words;
    const autosuggest = document.getElementById("autosuggest");
    autosuggest.addEventListener("selected_suggestion", (value) => {
      let words = value.detail.suggestion.words;
      // console.log(words);

      what3words.api
        .convertToCoordinates({ words: words, format: "geojson" })
        .then(function (response) {
          // console.log("[convertToCoordinates]", response);

          // loop the feature collection to get one feature at the time
          response.features.forEach((marker) => {
            // removing the marker anytime a new feature gets selected
            markers.forEach((marker) => {
              marker.remove();
            });
            markers = [];

            // create a HTML element for each feature
            const el = document.createElement("div");
            el.className = "marker";

            // make a marker for each feature and add to the map
            const mapMarker = new mapboxgl.Marker(el, {
              offset: [0, -64 / 2 + 3]
            })
              .setLngLat(marker.geometry.coordinates)
              .addTo(map);

            // save tmp marker into the markers list
            markers.push(mapMarker);

            /// center to the marker on the map
            map.jumpTo({
              center: marker.geometry.coordinates,
              zoom: 19
            });
          });
        });
    });
  }
</script>
Copied

Add a marker element to the CSS code snippet within the <style></style>.

.marker {
  background-image: url("https://what3words.com/map/marker.png");       
  background-size: cover;
  width: 64px;
  height: 64px;
  cursor: pointer;
 }
Copied
9Full example

The example below takes the concepts described in the step by step guide and turns some of them into a complete example. Here we have an AutoSuggest component place on a map, where we are listening for the select event. We are then using the what3words JavaScript Wrapper’s convert to coordinates functionality to get the coordinates for that address. With those coordinates we then refocus the map and drop a pin on the location selected.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <script src="https://api.tiles.mapbox.com/mapbox-gl-js/v1.12.0/mapbox-gl.js"></script>
    <script
      type="module"
      async
      src="https://cdn.what3words.com/javascript-components@4.2.2/dist/what3words/what3words.esm.js"
    ></script>
    <script
      nomodule
      async
      src="https://cdn.what3words.com/javascript-components@4.2.2/dist/what3words/what3words.js"
    ></script>
    <link
      href="https://api.tiles.mapbox.com/mapbox-gl-js/v1.12.0/mapbox-gl.css"
      rel="stylesheet"
    />
    <script>
      // Attach the what3words API to the window
      // and set the callback function for it
      window.w3w = {
        callback: "initW3w"
      };
    </script>
    <style>
      html,
      body,
      #map {
        position: absolute;
        height: 100%;
        width: 100%;
        margin: 0;
        padding: 0;
      }

      #autosuggest {
        position: absolute;
        top: 10px;
        left: 10px;
        z-index: 100;
      }

      #wrapper {
        position: relative;
        height: 100%;
      }

      .marker {
        background-image: url("https://what3words.com/map/marker.png");
        background-size: cover;
        width: 64px;
        height: 64px;
        cursor: pointer;
      }
    </style>
    <title>Autosuggest Component (Mapbox)</title>
  </head>
  <body>
    <div id="wrapper">
      <what3words-autosuggest id="autosuggest" api_key="YOUR-API-KEY">
        <input type="text" />
      </what3words-autosuggest>
      <div id="map"></div>
    </div>

    <script>
      function initW3w(what3words) {
        //pass your what3words API key to make calls to the what3words API
        what3words.api.setApiKey("YOUR-API-KEY");
        mapboxgl.accessToken =
          "pk.eyJ1IjoiZGV2ZWxvcG1lbnQtd2hhdDN3b3JkcyIsImEiOiJjang0ZjkxcHEwNTYxM3lrZTMxbTk0aDI2In0.8zBZh2m8pqvKcnbz3m_Mcg";
        const map = new mapboxgl.Map({
          container: "map",
          style: "mapbox://styles/mapbox/streets-v9",
          center: [-0.195499, 51.52086],
          zoom: 12
        });

        const nav = new mapboxgl.NavigationControl();
        map.addControl(nav, "bottom-right");

        // save current map markers in a list (as global variable)
        let markers = [];
        let words;
        const autosuggest = document.getElementById("autosuggest");
        autosuggest.addEventListener("selected_suggestion", (value) => {
          let words = value.detail.suggestion.words;
          // console.log(words);

          what3words.api
            .convertToCoordinates({ words: words, format: "geojson" })
            .then(function (response) {
              // console.log("[convertToCoordinates]", response);

              // loop the feature collection to get one feature at the time
              response.features.forEach((marker) => {
                // removing the marker anytime a new feature gets selected
                markers.forEach((marker) => {
                  marker.remove();
                });
                markers = [];

                // create a HTML element for each feature
                const el = document.createElement("div");
                el.className = "marker";

                // make a marker for each feature and add to the map
                const mapMarker = new mapboxgl.Marker(el, {
                  offset: [0, -64 / 2 + 3]
                })
                  .setLngLat(marker.geometry.coordinates)
                  .addTo(map);

                // save tmp marker into the markers list
                markers.push(mapMarker);

                /// center to the marker on the map
                map.jumpTo({
                  center: marker.geometry.coordinates,
                  zoom: 19
                });
              });
            });
        });
      }
    </script>
  </body>
</html>
Copied
WebsiteAdd a 3 word address input fieldUse 3 word addresses with a mapJavaScriptMapbox

Related tutorials