apologies I’m new to coding.
I have a webflow project that has some custom code which integrates google maps API with some basic javascript but I’m getting 2 warnings in the console that I really need help fixing.
I would truly appreciate the help from anyone on how I can solve this or even how I can generally improve on this code.
The Warnings:
1.
js?v=3.53.2,exp&key=…vvMFq3_8ccilrI0:266 Google Maps JavaScript API has been loaded directly without loading=async. This can result in suboptimal performance. For best-practice loading patterns please see https://goo.gle/js-api-loading
Ufa@js?v=3.53.2,exp&key=…vvMFq3_8ccilrI0:266
2.
js?v=3.53.2,exp&key=…vvMFq3_8ccilrI0:201 As of February 21st, 2024, google.maps.Marker is deprecated. Please use google.maps.marker.AdvancedMarkerElement instead. At this time, google.maps.Marker is not scheduled to be discontinued, but google.maps.marker.AdvancedMarkerElement is recommended over google.maps.Marker. While google.maps.Marker will continue to receive bug fixes for any major regressions, existing bugs in google.maps.Marker will not be addressed. At least 12 months notice will be given before support is discontinued. Please see https://developers.google.com/maps/deprecations for additional details and https://developers.google.com/maps/documentation/javascript/advanced-markers/migration for the migration guide.
The code:
<!-- Map container -->
<div id="map" style="height: 400px; width: 100%;"></div>
<!-- CMS Collection List (hidden) -->
<div id="locationsList" style="display:none;">
<!-- Webflow will populate this with Collection List Items -->
</div>
<script>
function initMap() {
const customIcon = {
url: 'https://cdn.prod.website-files.com/65722a8eff588d8e12dca16b/658d71462c0ec7b8fc92aad6_Untitled-9-01.svg',
scaledSize: new google.maps.Size(30, 30),
origin: new google.maps.Point(0, 0),
anchor: new google.maps.Point(15, 15)
};
let map;
let currentInfoWindow = null;
// Check if the map container exists
const mapDiv = document.getElementById('map');
if (!mapDiv) {
console.error('Map container not found');
return;
}
// Snazzy Maps style array
const snazzyMapStyle = [
// ... Your existing style array ...
];
map = new google.maps.Map(mapDiv, {
zoom: 14,
center: {lat: 35.231706, lng: 23.682403}, // Paleochora center
styles: snazzyMapStyle,
zoomControl: true,
mapTypeControl: false,
scaleControl: true,
streetViewControl: false,
rotateControl: false,
fullscreenControl: true
});
const locationItems = document.querySelectorAll('[data-location-item]');
const locations = Array.from(locationItems).map(item => ({
name: item.querySelector('[data-location-name]').textContent,
lat: parseFloat(item.querySelector('[data-location-lat]').textContent),
lng: parseFloat(item.querySelector('[data-location-lng]').textContent),
description: item.querySelector('[data-location-description]').textContent,
imageUrl: item.querySelector('[data-location-image]').getAttribute('src') || item.querySelector('[data-location-image]').textContent,
link: item.querySelector('[data-location-link]').getAttribute('href')
}));
// Store the HTML template as a constant
const infoWindowTemplate = document.getElementById('infowindow-template').innerHTML;
locations.forEach(location => {
console.log('Location Image URL:', location.imageUrl); // Debug log
const marker = new google.maps.Marker({
position: {lat: location.lat, lng: location.lng},
map: map,
title: location.name,
icon: customIcon
});
marker.addListener('click', () => {
if (currentInfoWindow) {
currentInfoWindow.close();
}
const infoWindowContent = infoWindowTemplate
.replace('id="location-name">', `id="location-name">${location.name}`)
.replace('id="location-description">', `id="location-description">${location.description}`)
.replace(/src="[^"]*"/, `src="${location.imageUrl}"`)
.replace('id="location-link" href="#"', `id="location-link" href="${location.link}"`);
console.log('Info Window Content:', infoWindowContent); // Debug log
const infoWindow = new google.maps.InfoWindow({
content: infoWindowContent
});
infoWindow.open(map, marker);
currentInfoWindow = infoWindow;
});
});
map.addListener('click', () => {
if (currentInfoWindow) {
currentInfoWindow.close();
currentInfoWindow = null;
}
});
}
// Load Google Maps API script dynamically
function loadGoogleMapsAPI() {
const script = document.createElement('script');
script.src = 'https://maps.googleapis.com/maps/api/js?v=3.53.2,exp&key=AIzaSyB52I0sX29SAyRXqb07vvMFq3_8ccilrI0';
script.async = true;
script.defer = true;
script.onload = initMap; // Call initMap after the script has loaded
document.head.appendChild(script);
}
// Ensure the DOM is loaded before loading the Google Maps API
document.addEventListener('DOMContentLoaded', loadGoogleMapsAPI);
</script>
What the code should do:
Google Maps Integration in Webflow
This code integrates Google Maps into a Webflow project, creating an interactive map with custom markers and info windows. Here’s a breakdown of its functionality:
-
HTML Structure:
- A div with id “map” is used as the container for the Google Map.
- A hidden div with id “locationsList” is presumably used to store location data from a Webflow Collection List.
-
Map Initialization (
initMap
function):- Creates a new Google Map instance.
- Sets the initial center to Paleochora (latitude 35.231706, longitude 23.682403).
- Applies custom styles (Snazzy Maps style, which is commented out in the provided code).
- Configures map controls (zoom, scale, fullscreen enabled; street view, rotate, map type disabled).
-
Location Data Processing:
- Retrieves location data from Webflow Collection List items.
- Each location includes: name, latitude, longitude, description, image URL, and link.
-
Marker Creation and Info Windows:
- Creates a marker for each location on the map.
- Sets up click listeners for each marker.
- Uses a template (not provided in the code snippet) to create custom info windows.
- Opens an info window when a marker is clicked, closing any previously opened info window.
-
Map Click Handling:
- Closes the currently open info window when clicking elsewhere on the map.
-
Google Maps API Loading (
loadGoogleMapsAPI
function):- Dynamically loads the Google Maps JavaScript API.
- Uses a Promise to handle successful loading or errors.
-
Initialization on DOM Content Loaded:
- Waits for the DOM to be fully loaded before initializing the map.
- Catches and logs any errors during the API loading process.
-
Security Note:
- I know the API key is exposed even though it’s restricted but can’t find a better solution using webflow. If a clever solution exists I’m all ears.
This implementation allows for a custom-styled map with location markers pulled from a Webflow Collection, providing an interactive and visually appealing map experience for users.
This is the code:
I’ve tried to fix error 2 by replacing google.maps.Marker
with google.maps.marker.AdvancedMarkerElement
But this then results in the following error:
map:67 Uncaught TypeError: Cannot read properties of undefined (reading 'AdvancedMarkerElement')at map:67:47at Array.forEach (<anonymous>)at HTMLScriptElement.initMap (map:64:15)(anonymous) @ map:67initMap @ map:64load loadGoogleMapsAPI @ map:112