All impact tools

Sheet Mapper

Create a live-updating map that displays the locations of all of your POIs or events, powered by a simple spreadsheet.

Live interactive demo map

Many organizations use spreadsheets to collaborate and collect data, so we are frequently asked how to create a map from data in this format.

This blueprint is appropriate for any organization trying to map a set of locations from a Google sheet — in order to display offices, emergency shelters, distributed events, and more.

This solution also can be used with more advanced functionality, including data joins to other tilesets, routing between locations, and more.

Maps built with this tool

Tutorial and templates


  1. Create data in a Google sheet 
  2. Copy in the map code
  3. Add your Mapbox access token
  4. Pick your map style
  5. Connect your table  
  6. Add layer to map
  7. Add popups
  8. Publish on Github Pages


Tools we’ll use:

Step 1: Create data in a Google sheet 

Set up a Google Spreadsheet with the data for your map. You can duplicate your sheet from this template or start your own. You need longitude and latitude for each point to place your map marker. Name, Address, and additional fields will be displayed in the popups.

Need help with generating lat/long points?  You can use Nominatim, an open-source OSM tool, for for forward and reverse geocoding.

  • Go to
  • Search an address in the search bar
  • Click the Details button, copy the coordinates listed in the Centre Point row, and paste into your spreadsheet.

Once your table is complete, set sharing settings to 'Anyone with the link can view' so the data is visible without granting access to modify it. In Google Sheets navigate to File → Publish to the Web. Select Comma-Separated Values (CSV) from the drop down menu and then click on the green Publish button.

Copy the Published Link URL and save this to a notepad or some other document to be used later. Your URL should look something like:

Step 2. Start your map code

Open a text editor and create a file called index.html. Set up the document by copying and pasting this template code into your new HTML file.

Step 3. Add your Mapbox access token

Without an access token, the rest of the code will not work.

Login or create a free Mapbox account. Find your access token on your Access tokens page or the main page you sign into your Mapbox account.

Note: We recommend using the url restriction feature on the token to avoid token misuse and want to emphasize that only public tokens should be posted to public repositories. You can find out more information about how to securely manage your access tokens here.

Copy and paste your access token into the code, here:

 // YOUR TURN: add your Mapbox access token 
mapboxgl.accessToken = 'Replace with your access token';

Step 4. Add a basemap style 

There are several Mapbox-designed map styles that you can choose "out of the box" or you can design your own using the Mapbox Studio style editor. Let’s use Mapbox Streets:

Add Streets Style to your map by replacing <Replace with a Mapbox style url> with mapbox://styles/mapbox/streets-v11.

 // YOUR TURN: add your Mapbox access token 
      mapboxgl.accessToken = "Replace with your access token";
      var map = new mapboxgl.Map({
        container: 'map', // container id
        style: "Replace with a Mapbox style url", // YOUR TURN: choose a style:
        center: [-122.411464, 37.7852299], // starting position [lng, lat]
        zoom: 9 // starting zoom

Step 5. Connect  your spreadsheet 

The code uses csv2geojson to retrieve data from the Google Sheet CSV export that you saved in Step 1 and convert into a geojson.

To connect your Google Sheet, replace the ‘url’ value with your Google Sheet export link.

    $(document).ready(function () {
        type: "GET",
        // YOUR TURN: Replace 'url' value to CSV export link 
        url: 'Replace with CSV export', 
        dataType: "text",
        success: function (csvData) { makeGeoJSON(csvData); }

Step 6. Add layer to the map

The next part of the code adds the layer to the map and specifies how it will be styled. In this example, the layer is added as a circle with a 5 px radius and the color is set to purple. You can read more about layer types and available paint and layout properties in the Mapbox Style Specification.

       //Add the the layer to the map 
              'id': 'csvData',
              'type': 'circle',
              'source': {
                'type': 'geojson',
                'data': data
              'paint': {
                'circle-radius': 5,
                'circle-color': "purple"

Step 7. Add popups

When a user clicks a symbol we want to show a Popup containing more information about the locations stored in our spreadsheet. The text for each popup is set to the fields ‘Name’, ‘Address’, and ‘Phone’.

 // When a click event occurs on a feature in the csvData layer, open a popup at the
            // location of the feature, with description HTML from its properties.
            map.on('click', 'csvData', function (e) {
              var coordinates = e.features[0].geometry.coordinates.slice();

              //set popup text 
              //You can adjust the values of the popup to match the headers of your CSV. 
              // For example: e.features[0].properties.Name is retrieving information from the field Name in the original CSV. 
              var description = `<h3>` + e.features[0].properties.Name + `</h3>` + `<h4>` + `<b>` + `Address: ` + `</b>` + e.features[0].properties.Address + `</h4>` + `<h4>` + `<b>` + `Phone: ` + `</b>` + e.features[0].properties.Phone + `</h4>`;

              // Ensure that if the map is zoomed out such that multiple
              // copies of the feature are visible, the popup appears
              // over the copy being pointed to.
              while (Math.abs(e.lngLat.lng - coordinates[0]) > 180) {
                coordinates[0] += e.lngLat.lng > coordinates[0] ? 360 : -360;

              //add Popup to map

              new mapboxgl.Popup()

            // Change the cursor to a pointer when the mouse is over the places layer.
            map.on('mouseenter', 'csvData', function () {
              map.getCanvas().style.cursor = 'pointer';

            // Change it back to a pointer when it leaves.
            map.on('mouseleave', 'places', function () {
              map.getCanvas().style.cursor = '';

            var bbox = turf.bbox(data);
            map.fitBounds(bbox, { padding: 50 });


If you want to add different fields, change the display text (e.g. ‘Address:’) and the e.features[0].properties.columnName (e.features[0].properties.Address) to match the corresponding column label in your csv.

Step 7. Publish your map 

You’ve made a web map! But it isn’t a webpage yet… to do that we need some way to host a webpage. There are many different ways to host a webpage. Github Pages is one good solution.

Publish your map with Github Pages 

  1. Create an account at Github if you don’t have one.
  2. Create a new Github repository:
    - Name it for your map (this will be visible in the url).
    - Make it Public
    - Click the box to ‘Initialize this repository with a README’
  3. Create a new file called index.html
  4. In the blank index.html file, paste in the entire edited code that you built in your text editor (in Steps 2 - 6).
  5. Enable Github Pages (in the repository Settings, which you access using the gear symbol in the upper right). Follow Github’s instructions for a Project Site.
  6. fter a minute or two, your Github Page URL will be published online. It will look something like https://[YOUR GITHUB NAME][YOUR REPO NAME]/ - you can find your URL navigating back to the Github Pages section in your repository settings.

Finished project

View our finished example map at

Need more help? Ask questions on Stack Overflow or contact Mapbox Support. If you are working on a social good project, contact the Mapbox Community Team.

Want to share what you’ve built? Tweet it with #builtwithmapbox