Display multiple locations with Google Maps API, driven dynamically by Webflow's CMS
Credits:
This script is adapted from Anna Sabatini's dynamic Google Maps project
The Setup
Create a container for your Map
Add a div to display the actual map. Give it an ID of ‘map’
Set up your location collection fields
Create a collection and configure your fields. Add all the fields you’ll need, and make sure to include these required fields
- Lat
- Long
- Etc etc
Create a Custom Marker
Design and export your custom marker. Use a simple SVG for best results, or a PNG. Upload to your Webflow Assets and grab the Asset URL.
(If your use case requires, you can also create a custom pin for each location by using a collection field and dynamically referencing it in the code.)
Style your info window
Get your Google Maps API key
Get your API key, and restrict usage to your main and staging domains.
Configure Map Styles
Use the map styler to configure the look, feel and features of your map.
Associate the map style with your Map API project, and copy the map style ID — we’ll reference this in the code later:
The magic code
Add API key between script tags
First, make sure the script has been added to your page.
We’d like to only run the page after the page loads
We need our CMS items to load before we execute the code to avoid errors. We can use the event listener function here to wrap our code:
Create some variables
We’ll start creating some variables to reference in our script.
1. Let’s create variable to hold our locations in an array:
2. Next, we need to get each item of our location list by referencing the class we added to the collection item wrapper and adding to a variable called ‘dynPlaces’. Now that we’ve found each location item on the page (‘dynPlaces’ variable), we’ll add in all the dynamic data from the CMS for each item so that we can use it. For each element in the dynPlaces list, we’ll create a ‘place’ variable, and reference some of the CMS data fields we created including the Title, Latitude, Longitude, and Info Window content. Finally, we’ll push the place data into the locations array we created earlier.
Now, we have we can reference Locations as a list > Each location as an item > and display each item’s unique data.
Configure Map
Make sure you take a look at the Google API docs to see the configuration options available, and adjust to your needs.
First, we’ll create a ‘map’ variable, and use the API guide to create a new map and place it into the map container we created by referencing the container ID, in this case the ID is simply ‘map’. Use the container ID you created, any name is fine as long as what you use the code below matches the ID you added in the designer.
Paste the MAP ID from your google maps profile.
Create Info Windows
Create a variable and tell the api to create info windows:
Configure the Marker function
Add a function to create the dynamic markers. In the function, we’ll create a variable, reference data and the map, and add the custom marker icon URL we created here:
Configure Info Windows open/close for each marker
When a user clicks on a marker, we’d like to show the info window. For this, we’ll engage add an event listener to get then content and display open the info window.
Create the markers and info windows for each location and add it to the map
Now that the marker and info windows have been configured and saved in variables, we’ll create one for each location in our CMS collection and add it to the map.
gmarkers = [];
for (var i = 0; i < locations.length; i++) {
gmarkers[locations[i][0]] =
// passing lat and long
createMarker(new google.maps.LatLng(locations[i][2], locations[i][3]),
// passing Info-window information
locations[i][1]);
}
Set map bounds
Set the zoom level and map bounds for your use case (reference google maps Api docs here)
// Create map bounds and center map
var bounds = new google.maps.LatLngBounds();
// Northwest bound
var northwest = new google.maps.LatLng(55.738514, 12.462881);
// Southeast bound
var southeast = new google.maps.LatLng(55.627170, 12.660888);
bounds.extend(northwest);
bounds.extend(southeast);
map.fitBounds(bounds);
map.setCenter(bounds.getCenter());
}, false);
And that should do the trick!
Adding a new CMS item will create a new map pin, list item, and info window.
Clicking a collection list item should now highlight and centre it on the map.
Clicking a marker on the map should center it and open the info window.
Good luck!
Working Example:
Clonable:
Full script:
<script async defer src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap" type="text/javascript">
</script>
<script>
// Run code when page loads
window.addEventListener('load', function () {
// Create a locations array
var locations = []
// Add .locations_item class to the location Collection Item
var dynPlaces = document.querySelectorAll('.w-dyn-item.locations_item');
// Define variables for the map info window
dynPlaces.forEach( function(elem) {
// Create places array
var place = [];
// Define variables for each place
var dataTitle = elem.querySelector('.data---slug').innerText; // Define slug for targeting the information window
var dataLat = Number(elem.querySelector('.data---latitude').innerText); // Define latitude point for pin
var dataLong = Number(elem.querySelector('.data---longitude').innerText); // Define longitude point for pin
var infoWindowContent = elem.querySelector('.locations_data-info-window').innerHTML; // Define content wrapper for the information window
// Add variables to each place
place.push(dataTitle, infoWindowContent, dataLat, dataLong);
// Add each place to the locations array
locations.push(place);
});
// Map settings
var map = new google.maps.Map(document.getElementById('map'), {
mapId: ‘YOUR_MAP_ID’,
streetViewControl: false,
mapTypeControl: false,
fullscreenControl: false,
scrollwheel: false,
});
// Create info windows
var infowindow = new google.maps.InfoWindow();
// Create markers
function createMarker(latlng, html) {
var marker = new google.maps.Marker({
position: latlng,
map: map,
icon: “YOUR_ICON_URL”
});
// Define info window for each marker
google.maps.event.addListener(marker, 'click', function() {
infowindow.setContent(html);
infowindow.open(map, marker);
});
return marker;
}
gmarkers = [];
for (var i = 0; i < locations.length; i++) {
gmarkers[locations[i][0]] =
// passing lat and long
createMarker(new google.maps.LatLng(locations[i][2], locations[i][3]),
// passing Info-window information
locations[i][1]);
}
// Create map bounds and center map
var bounds = new google.maps.LatLngBounds();
// Northwest bound
var northwest = new google.maps.LatLng(55.738514, 12.462881);
// Southeast bound
var southeast = new google.maps.LatLng(55.627170, 12.660888);
bounds.extend(northwest);
bounds.extend(southeast);
map.fitBounds(bounds);
map.setCenter(bounds.getCenter());
}, false);
</script>
Unlock your website business
Let's kickstart this exciting journey with an obligation-free initial consultation. Click below to contact, or send an email to jkrdesignsa@gmail.com