Prototyping with real data allows you to build realistic interactions and create better user experiences. If you’re designing a location-based application, you can add real geographic data to Framer prototypes with Mapbox developer tools. The data can be read and updated in real-time with only a few lines of code.

Here’s a quick look into how we create location data, fetch it dynamically, display custom markers on a map, and update data directly through user interactions.

1. Create location data with Mapbox Studio dataset editor

The Mapbox Studio dataset editor, now in private beta, lets you create points, lines, and polygons by drawing on a map or importing files.

Let’s use a travel planning app as an example. We’ll need to create some landmarks as example map data in the dataset editor. First, type in the place name in the search bar and click the “add point to location” button to add a feature. Then, add some additional properties to that feature like a telephone number, description, and address.

You can always come back to the editor and modify the data. The changes will be immediately reflected in your Framer projects after saving.

2. Fetch data with the Mapbox Datasets API

Once you create the POI data, you can access them directly through the Mapbox Datasets API. The Mapbox JavaScript SDK makes it simple to interact with the API.

First, install Mapbox JavaScript SDK as a Node.js module:

cd ~/my-framer-project
npm install mapbox

In the modules folder, create a new file and name it npm.coffee, then add:

exports.mapbox = require "mapbox"

Then, use the listFeatures method to fetch the data. You will need two things: 1) A dataset ID, you can find the ID from the dataset view page. 2) An access token with scopes datasets:read and datasets:write. You can create one from the token page of Mapbox Studio. The code will look like this:

{ mapbox } = require "npm"
mapboxAccessDatasetToken = "your_access_token"
datasetID = "your_dataset_id"
mapboxClient = new mapbox(mapboxAccessDatasetToken)

# Use the listFeatures method to fetch data
mapboxClient.listFeatures(datasetID, {},
 (err, dataset) ->
   print err if err
   # Create a list of locations
   for feature,i in dataset.features
     locationTitle = new Layer
       html: feature.properties.place_name + feature.properties.address
)

3. Turn data into custom markers on a map

Since your data is stored as GeoJSON features, you can easily turn them into interactive markers on a map with Mapbox GL JS. First, we’ll need to install GL JS as a module and add a map into your prototype. Read our guide to Mapbox + Framer for more details.

After you add the map, add the dataset as a source to the map:

map.on("load", () ->
  map.addSource("points",
    {"type": "geojson", "data":
      {"type": "FeatureCollection", "features": dataset.features}})
  )

The data that you created with the dataset editor is stored as GeoJSON and includes longitude and latitude coordinates. This makes it easy to retrieve the data on a live map and style the data in any way you want with libraries like Mapbox GL JS. You can also add interactions to the map that correspond to specific mouse or touch events. For example, when clicking on a marker, add an active class to that marker and trigger the state switch function of a layer:

dataset.features.forEach (feature, i) ->
  img = document.createElement('img')
  img.className = "location-marker"
  # use images as markers on the map
  img.style.backgroundImage = "url('images/" + (i + 1) + ".png')"
  marker = new mapboxgl.Marker(img).setLngLat(feature.geometry.coordinates).addTo(map)
  img.addEventListener("click",() ->
    # add an active class
    highlightedMarkers = document.querySelectorAll('.active')
    for highlightMarker,i in highlightedMarkers highlightMarker.classList.remove('active')
    img.classList.add('active')
    # switch marker content when clicking
    markerContent.states.switch(i)
)

4. Design realistic interactions

You can also update the data in real-time by using the insertFeature method of the Datasets API. This will help you create more advanced interactions, such as rating a restaurant or adding a museum to a travel list.

In this example, after a user submits a new rating, the updateReviewScore function fetches the latest data and recalculates the count and score, and then the updateFeature function updates this specific feature with the new count and score. When people interact with this prototype, they can see the review score and count changing and get instant feedbacks from their actions.

# Use the on function to listen for the click event
confirmRateThis .on Events.Click, ->
  featureID = markerContent.name
  updateReviewScore(featureID, newScore)

updateReviewScore = (featureID, newScore) ->
  # Fetch the latest feature
  mapboxClient.readFeature featureID, datasetID, (err, feature) ->
    oldScore = feature.properties.review_score
    oldCount = feature.properties.review_count
    feature.properties.review_score =
    (oldScore * oldCount + newScore)/(oldCount + 1)
    feature.properties.review_count = oldCount + 1
    updateFeature(feature)

# Update the feature with the new data
updateFeature = (feature) ->
   mapboxClient.insertFeature feature, datasetID, (err, feature) ->
       generateContentPageContent(feature)
       clearRateModal()

You can download and view the full code example from here. Want early access to Mapbox Studio dataset editor? Sign up here.