The Ultimate Guide on How to Build a Custom Google Map

Custom Google Map, made by Frontend Hero

Enhancing your website with an interactive custom Google map can be beneficial for visitors looking for the location of your business (or businavinesses) at a quick glance, so integrating a slick Google Map that matches your website’s style is important to give your brand that little touch of professionalism.

We are going to be using Google Map’s API which unfortunately now requires a billing account since Google changed how access to their api works in 2018, but don’t worry, as Google gives us Β£200 free credits every month which should be more than enough for most website owners.

You can view the live demo here.

If you already have your Google Maps API key, you can skip the first part of this tutorial and go straight into creating the map.

Ok, this guide is a tad long, so you might want to get a brew ready and settle in, as we create our map. Let’s go!

1. Create a Google Maps Project/API Key

This will take a little bit of time as there a few hurdles to jump through before we can get to the fun stuff!

1.1. Create a Google Maps Project

First off, you are going to have to log into your Google Cloud console account and either select an existing project or create a brand new one.

For this tutorial, let’s create a new project.

So go ahead and create your project name, link your billing account, and optionally add an organisation.

Once those details have been filled in, press the create button.

1.2. Create Your Google Maps API key

After you’ve clicked the create button on the previous new project page, you’ll automatically be brought to the credentials page of this newly created project. This is where we’ll create an API key to gain access to the Maps platform.

Once the credentials page has loaded, click the + Create Credentials link to open the dropdown menu, and click the first option in the dropdown menu titled API key.

After a few seconds of loading, Google will return your newly created API key. Save this for later but don’t close the modal.

1.3. Restrict Your Google Maps API key

Now that we have our Google Maps API key we are nearly ready to start coding but we first need to restrict the API key to our website that the map will reside on. In this example, I’m going to restrict the key to the Front-end Hero URL.

Restricting the API key will stop any random person or bot just viewing the source code and copying our API key and using it in their website/application. The ramifications of this could potentially be huge, if for example a person included our API key on a high traffic website with thousands upon thousands of requests, we’d then be left with a big bill from Google. πŸ’Έ

With that said, click on the Edit API key link on our API key modal box to begin the process of restricting our API key.

1.4. Set an application restriction

First, we select Websites from the list of platforms/IP addresses to restrict.

1.5. Website restrictions

Next we just add the restricted website. In my case, Frontend Hero‘s URL. Once your domain has been added, click Done.

# Make sure to follow the format like below:

*.domain.com/*

1.6. API restrictions

You can also restrict your Maps API key to specific APIs from Google. It might be something to consider if you work in a company that uses multiple Google APIs. As for myself, I will leave this to Don’t restrict key.

1.7. Enable Your Google Maps API Key

Last piece of the puzzle is to enable the Google Maps API.

If we try to use the key without first enabling it, the console would produce an error.

Google Maps JavaScript API error: ApiNotActivatedMapError
https://developers.google.com/maps/documentation/javascript/error-messages#api-not-activated-map-error

Now we just need to enable the API by navigating to the Google Maps API overview page and clicking Enable.

Right, we’re finally done setting up our API key. Now onto the fun part!

2. Create & Set Up The HTML, CSS, and JavaScript

I’ll be using two files for this little project. One HTML page index.htm and one JavaScript file main.js.

The CSS will be added into our HTML file, internally, as we won’t be using many styles.

  • index.htm
  • main.js
<!doctype html>
<html>

  <head>
    <meta charset="UTF-8">
    <title>How to build a stylish Google Map with custom location markers</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
  </head>

  <body>
    
  </body>

</html>
// coming soon

2.1. Add Boilerplate HTML, CSS, Google Maps Library, and Map Placeholder

Now, let’s add in some important pieces so we can start coding.

  • index.htm
  • main.js
  • Result
<!doctype html>
<html>

  <head>
    <meta charset="UTF-8">
    <title>How to build a stylish Google Map with custom location markers</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    
    <style>
      * { padding: 0; margin: 0; }
      html, body { height: 100%; }
      body { display: flex; }
      
      #google-map {
        margin: 0 auto 0 auto;
        border: 1px solid #ccc;
        width: 700px;
        height: 500px;
        align-self: center;
      }
    </style>
    
  </head>

  <body>
    <div id="google-map"></div>
  </body>
  
  <script defer src="https://maps.googleapis.com/maps/api/js?key=YOURAPIKEY&callback=initMap"></script>

</html>
// coming soon

Notes

  • I’ve added a <style> block to do the following:
    • Reset the page’s padding and margin.
    • Make the page 100% in height.
    • Make the body flex so we can easily vertically center the map.
    • Centered the Google map div #google-map, gave it a grey border and specified a height and width.
  • I’ve added in the div <div id="google-map"></div> where our map will be stored.
  • And finally, I’ve added the Google Maps API script.
<script defer src="https://maps.googleapis.com/maps/api/js?key=YOURAPIKEY&callback=initMap"></script>

3. Let’s Display a Google Map!

Let’s now display a simple Google map that will be centered in on London, UK and then we can expand upon this as we progress.

3.1 Create Our initMap() Function

We will create a function called initMap(). This name must match the name that you append to the Google Maps API script tag as a callback callback=initMap.

Our initMap() function is going to house all of our JavaScript code that will display our stylish map (If I do say so myself).

  • main.js
  • Result
function initMap() 
{		
   const mapOptions = {}
		
   const map = new google.maps.Map(document.getElementById("google-map"), mapOptions);
}

OK, we’re finally seeing something being displayed, albeit just a grey box at the moment, as we need to provide a few mandatory options to the map object.

Notes

  • First, we’ll create a blank mapOptions object that we will populate in a bit.
  • Then create a new Google Maps object google.maps.Map that will target our #google-map div and be placed inside when the page is loaded. We’ll also pass in our mapOptions object.

3.2. Add In Map Options and Get Center of Map Coordinates

As above, If we attempt to view our map in a browser, we won’t see anything of substance just yet, only a grey box. We need to provide two required options to our mapOptions object first:

  • center: This is an object that holds latitude and longitude coordinates that will tell the Maps API where to center our map, upon the initial load of the page.
  • zoom: We need to tell the Maps API what level of zoom we want our map displayed at.
  • main.js
function initMap() 
{
   const centerMap = {} // We'll add in some options shortly
		
   const mapOptions = {
      center: centerMap, // coordinates to center map
      zoom: 10, // level of zoom we want
   }
		
   const map = new google.maps.Map(document.getElementById("google-map"), mapOptions);	
}

Notes

  • We’ve created a variable called centerMap, that, at the moment is an empty object {}.
  • We’ve added the required options to our mapOptions object; center: new google.maps.LatLng(centerMap) and zoom level.

Ok, we now need to populate the centerMap variable, so the map will show.

3.3. Get GPS Coordinates of London, UK.

This map will be using London, UK as our base, so we need to head over to Google Maps and search for London, UK.

Once the London map has loaded, we can then go ahead, navigate to the address bar of our browser and locate the coordinates from the URL.

https://www.google.com/maps/place/London/@51.5285578,-0.242025,11z

Or more specifically:

51.5285578,-0.242025

Let’s add these in to our centerMap object with each value’s property name: lat and lng.

  • main.js
  • Result
  • Alignment Issue
function initMap() 
{
   const centerMap = {lat: 51.5285578, lng: -0.242025 }
		
   ...		
}

Huzza! We have now displayed our Map! Pretty cool. But… you might notice that our map is slightly out of alignment (See above tab labelled alignment issue). This is because when we searched for London, UK, Google didn’t exactly display our desired location in the center of the browser; Google seems to push the location to the right hand side a bit, maybe as they have a prominent left hand sidebar that they need to account for.

3.4. Fix Center of Map Alignment

As a stickler, let’s go back to our London, UK location on Google Maps and drag London to be as close to the center as possible.

  • Fixed Center of Map

Much better, let’s proceed.

3.5. Remove UI Clutter From Map

As we can see in our example, the map shows a few options such as :

  • Map/Satellite view.
  • Fullscreen option.
  • Pegman/streetview icon.
  • Increase/decrease zoom.

Let’s remove these elements by adding disableDefaultUI: true to our mapOptions, and clean up our map.

  • main.js
  • Result
const mapOptions = {

   ...
   
   disableDefaultUI: true
}

4. Let’s Add Some Markers To Our Map

As I’m a huge cake lover, I’m going to add a few of my favourite bakery locations to our map 🍰.

4.1. Create array of marker objects

We’ll first create an array called markers that will hold each bakery’s information:

  • Name of bakery.
  • Latitude and longitude coordinates.
  • Address of bakery.

We only need the latitude and longitude coordinates for each marker but we’ll add a few more properties such as locationName, and address as we’ll be using this information later on.

For the moment, we have a nice template to start adding our locations to. In the next step, we’ll populate these properties with real data.

  • main.js
function initMap() 
{
   /** 
   * Barebones array with object/properties.
   */
   const markers = [
      {
         locationName: '', 
         lat: LAT, 
         lng: LNG, 
         address: ''
      }
   ];

   ...
		
}

4.2. Populating the Markers Array With Bakeries

Now, let’s add in real world data from a few locations.

4.2.1. Here Are the Bakeries I Will Be Adding for Reference:

4.3. Navigate to Google Maps and Get Bakery Information

We will need the name, coordinates, and the address of each bakery.

We can get the coordinates of each location by right clicking the map pin after you’ve searched for a bakery (try right clicking as close to the bottom of the pin as possible for more accurate coordinates).

For example, searching for Crumbs & Doilies – we can right click on it’s pin and the first link in the menu is the GPS coordinates: 51.512222624233566, -0.13840734189018739. Click these and it will copy them to your clipboard.

We’ll do this for the five bakeries listed above and then add in the information for each marker element.

You’ll also notice, I’m including line breaks <br> in each address. We’ll come back to this later.

  • main.js
  • Getting Map Coordinates
const markers = [
   {
      locationName: 'Crumbs & Dollies', 
      lat: 51.512222624233566,
      lng: -0.13840734189018739, 
      address: '1 Kingly Ct,<br> Carnaby, London,<br> W1B 5PA'
   },
   {
      locationName: 'Rinkoff Bakery', 
      lat: 51.52026231452749, 
      lng: -0.052815725337595015,
      address: '222-226 Jubilee St,<br> London,<br> E1 3BS'
   },
   {
      locationName: 'Comptoir Gourmand Bermondsey', 
      lat: 51.500874447971604,
      lng: -0.0819699,
      address: '96 Bermondsey St,<br> London,<br> SE1 3UB'
   },
   {
      locationName: 'Bageriet',
      lat: 51.51195028807007,
      lng: -0.12619283058494118,
      address: '24 Rose St,<br> London,<br> WC2E 9EA'
   },
   {
      locationName: 'Ole & Steen',
      lat: 51.50635804760832, 
      lng: -0.017434353136203003,
      address: 'CR34 Crossrail Pl,<br> London,<br> E14 5AR'
   }
];

Excellent, we’ve got our array of markers created, but they won’t show up on the map just yet – we need to add these markers to the map.

But before we show all of our markers on the map, I think it will be beneficial to display the first bakery in our array to start with, to show you what’s going on.

  • main.js
  • Result
function initMap() 
{
   const markers = [
      // our array of bakery array elements
   ];

   const centerMap = { lat: 51.5114675, lng: -0.1266686 }
				
   const mapOptions = {
     // our map options
   }
		
   const map = new google.maps.Map(document.getElementById("google-map"), mapOptions);

   const marker = new google.maps.Marker({
      position: { lat: markers[0]['lat'], lng: markers[0]['lng'] },
      map: map
   });
}

Notes

We create a new marker constructor called marker: const marker = new google.maps.Marker. We pass in some options via an object literal: position, and map for the pin to show up at it’s correct location.

  • position: here we specify the coordinates of our first marker in our markers array by using these values: markers[0]['lat'] and markers[0]['lng']. As JavaScript arrays are zero-indexed: the first element of an array is at index 0, and then we target the lat and lng object property values.
  • map: specifies which map to place the marker.

In summary for this part, the below code…

position: { lat: markers[0]['lat'], lng: markers[0]['lng'] }

… could also be written as:

position: { lat: 51.512222624233566, lng: -0.13840734189018739 }

But instead of individually creating each marker, we are going to use a loop to help us create all five markers, in the next step.

5. Loop Through and Create All Markers

As our markers are sitting neatly in an array, we will first find out how many elements we have, and then create a loop to iterate through them all and create a marker constructor for each of our five bakeries.

  • main.js
  • Result
function initMap() 
{
   const markers = [
      // our array of bakery array elements
   ];

   const centerMap = { lat: 51.5114675, lng: -0.1266686 }
				
   const mapOptions = {
     // our map options
   }
		
   const map = new google.maps.Map(document.getElementById("google-map"), mapOptions);

   for (let i = 0; i < markers.length; i++) 
   {
      const marker = new google.maps.Marker({
         position: { lat: markers[i]['lat'], lng: markers[i]['lng'] },
         map: map
      });
   }
}

Yay, we now have a map filled with our my favourite bakeries! – It’s a bit off center but we’ll sort that out shortly πŸ˜‰

Notes

We create a for loop to iterate over the number of elements we have in our markers array (which is five) for (let i = 0; i < markers.length; i++){} and count the elements using markers.length.

In our previous example of displaying the first element of our bakeries/markers array, we targeted the first array item by using 0 (As JavaScript arrays are zero-indexed). Now we change this hard coded value and use our loop counter, which is called i to run through all five bakeries and output the lat and lng values of each marker object. So, each iteration, will be 0, 1, 2, 3, 4 – or five iterations.

6. Replacing the Default Marker Icon With a Custom Icon

Now let’s spruce up our markers and replace the default pin with a custom icon.

I’m going to use the logo from Frontend Hero and bring the size down a touch in my graphics editor, and then save it as a transparant PNG image. The size you want to make this icon is up to you – play around with the sizing by viewing your icon on the map, and adjust from there.

The size of image that I’ve used is 29px x 45px.

6.1. Adding Our Custom Icon to Our Locations

Adding in our custom icon is super easy, we just have to create a variable to hold the path of the image. I’ve called mine fehMarker.

  • main.js
function initMap() 
{		
   const markers = [
      // our array of bakery array elements
   ];

   const fehMarker = 'https://www.frontendhero.dev/wp-content/uploads/2023/03/feh-marker.png';

   ...

}

Now, we’ll add this variable into our const marker = new google.maps.Marker constructor.

We just need to add in a new option to our options icon: fehMarker.

  • main.js
  • Result
function initMap() 
{
   const markers = [
      // our array of bakery array elements
   ];

   const fehMarker = 'https://www.frontendhero.dev/wp-content/uploads/2023/03/feh-marker.png';
		
   ...
		
   for (let i = 0; i < markers.length; i++) 
   {
      const marker = new google.maps.Marker({
         position: { lat: markers[i]['lat'], lng: markers[i]['lng'] },
         map: map,
         icon: fehMarker
      });
   }
}

Brilliant, another piece of the puzzle has been ticked off, we have custom markers πŸ₯³

Next up, let’s add some interactivity, so that we can allow users to click on each bakery/marker and view it’s information.

7. Adding Google Maps Info Windows to Each Marker

It’s all well and good displaying markers on our map, but Google does state that they should be interactive.

Markers are designed to be interactive. For example, by default they receive 'click' events, so you can add an event listener to bring up an info window displaying custom information.

https://developers.google.com/maps/documentation/javascript/markers

So let’s now allow users to click on each marker/bakery and view information related to that location.

7.1. Creating an Info Window Constructor

First, we need to create our infoWindow constructor, and add in some options to control the width of the window; using both minWidth, and MaxWidth.

We’ll use this infoWindow in the next step to add content to.

We’ll add this code block just before the loop.

const infoWindow = new google.maps.InfoWindow({ 
   minWidth: 200, 
   maxWidth: 200 
});

7.2. Add Click Event to Each Marker and Display Blank Info Window

Now we can create a function createInfoWindows() that will hold each marker’s information, and create an info window for each marker. We add this function inside the loop.

function createInfoWindows() 
{
   const infoWindowContent = `
      <div class="feh-content"></div>
   `;
				
   google.maps.event.addListener(marker, "click", function ()
   {
      infoWindow.setContent(infoWindowContent);
      infoWindow.open(map, marker);
   }); 
}
createInfoWindows();
			

Notes

  • infoWindowContent is a placeholder for our content. For the moment, we’ll just get the window to show, and add in some information in a bit.
  • We’ll add a click event to each marker google.maps.event.addListener, so that when a marker is clicked it will put our infoWindowContent content into the infoWindow constructor, and then open it.
  • main.js
  • Result
function initMap() 
{
   const markers = [
      // our array of bakery elments			
   ];

   ...
		
   const infoWindow = new google.maps.InfoWindow({
      minWidth: 200,
      maxWidth: 200
   });
		
   for (let i = 0; i < markers.length; i++) 
   {
      ...

      function createInfoWindows() 
      {
         const infoWindowContent = `
            <div class="feh-content"><div>
         `;
				
         google.maps.event.addListener(marker, "click", function ()
         {
            infoWindow.setContent(infoWindowContent);
            infoWindow.open(map, marker);
         }); 
      }
      createInfoWindows();
   }
}

Great, it works, we get a blank info window.

Now we can populate these five info windows with our markers information.

7.3. Add Bakery Name and Address to Each Marker

Let’s populate infoWindowContent with the markers array elements, or bakeries 🍰.

  • main.js
  • Result
function createInfoWindows() 
{
   const infoWindowContent = `
      <div class="feh-content">
         <h3>${markers[i]['locationName']}</h3>
         <address>
            <p>${markers[i]['address']}</p>
         </address>
      <div>
   `;

   ...
}

Awesome stuff, we now have our map displaying all five bakeries, with a custom icon, and info windows with the name of the bakery, and location πŸ‘πŸ».

Notes

  • I’m using a template literal const infoWindowContent = ``; to store our content, and to easily output our information.
  • In our feh-content div, I’ve included a h3 and address tags.
  • Then I pull in the info, again, from our markers array.
    • ${markers[i]['locationName']}
    • ${markers[i]['address']}
  • Earlier we mentioned that we used line breaks in our address property of our markers array/objects. The reason being is only for aesthetics; having each address line on each line.

7.3.1. Tidy up Text in Info Window

We’ll clean up the text in the content window a bit, as I think it doesn’t look the best πŸ‘€.

Let’s pop back into our style block in index.htm and tweak our text styles.

<style>

   ...

   .feh-content * { font-family: 'uniform'; }
   .feh-content h3 {
      font-weight: 500;
      margin-bottom: 10px;
   }
   .feh-content p {
      font-style: normal;
      line-height: 16px;
      font-weight: 400;
   }

</style>

Much better 😍

Notes

  • As we have a content wrapper called feh-content in place, in infoWindowContent, I’m going to use this and target every child in this div with a wildcard * and make the font-family set to this website’s font: Uniform. (I already have this font installed as a webfont – If you would like to change the font family to something non standard, you will have to install your own webfonts).
  • I’ve also added this custom font in the head section index.htm
    • <link rel="stylesheet" id="uniform-css" href="...fonts.css" type="text/css" media="all">
  • I’ve tweaked the font-weight, font-size, and font-style to be cleaner (IMO), and then given the area between the heading and address a bit of breathing room.

8. Fix Alignment of Our Icons on Map

As we said earlier, the map is a bit off center, now that we have five bakeries scattered around the city. That’s because we are still using the London, UK coordinates to center our map, so it’s technically correct, but we now need to update the new center point.

We could create a new centerMap lat/lng, that would include all of our bakeries nicely centered on the map.

But… what if we wanted to include more bakeries (or exclude some) in the future, we’d have to update this again by manually dragging Google Maps around and testing a bit to find the center point of our updated bakery locations πŸ‘ŽπŸ».

What if we could just let The Google Maps API center the map on all of our markers for us? It just so happens that Google gives us this functionality and makes it super easy to do so.

8.1. Adding All Markers to bounds Object

Let’s create a new google.maps.LatLngBounds object and assign it to a variable, named bounds.

This will be created just before the loop.

const bounds = new google.maps.LatLngBounds();

And then in the loop, we’ll iterate over each marker and add them to this object with the help of bounds.extend.

Finally, we’ll use map.fitBounds to fit all of our markers in the map.

// inside for loop
bounds.extend(new google.maps.LatLng(markers[i]['lat'], markers[i]['lng']));		
map.fitBounds(bounds); 

Here’s the result.

  • Result

Pretty cool, but just one more niggle we can fix.

9. Recenter Map When an Info Window Is Closed

Currently, if you navigate around the map, open and close a marker, the map stays in the same position. Not a huge deal overall, but let’s add a tweak here to recenter the map after a window is closed.

As we’ve already created a bounds object in the previous step, we can use the method map.fitBounds(bounds) when an InfoWindow is closed to recenter the map.

  • main.js
  • Result
// added just after createInfoWindows();
google.maps.event.addListener(marker, "click", function ()
{
   infoWindow.setContent(infoWindowContent);
   infoWindow.open(map, marker);
}); 

10. Changing the Default Google Map Colour Scheme

We have a stylish little map that works really well, the last thing we need to do is change the colour scheme to blend in more with Frontend Hero‘s colour scheme.

There is an awesome website to help us visually build our colour scheme called Snazzy Maps, that gives us the JSON code for use in our code. We then add this JSON into our mapOptions as a styles property.

I won’t go into the specifics of my colour scheme here, as you can colour your map as you see fit, but here is the JSON that I have created, just by playing around:

  • Snazzy Maps JSON
  • main.js
  • Result
[
   {
      "featureType":"administrative",
      "elementType":"all",
      "stylers":[
         {
            "visibility":"on"
         }
      ]
   },
   {
      "featureType":"administrative",
      "elementType":"labels.text.fill",
      "stylers":[
         {
            "color":"#444444"
         }
      ]
   },
   {
      "featureType":"landscape",
      "elementType":"all",
      "stylers":[
         {
            "color":"#f3f3f3"
         }
      ]
   },
   {
      "featureType":"landscape.natural",
      "elementType":"all",
      "stylers":[
         {
            "color":"#cccccc"
         }
      ]
   },
   {
      "featureType":"poi",
      "elementType":"all",
      "stylers":[
         {
            "visibility":"off"
         }
      ]
   },
   {
      "featureType":"road",
      "elementType":"all",
      "stylers":[
         {
            "saturation":"0"
         },
         {
            "lightness":"0"
         },
         {
            "visibility":"simplified"
         }
      ]
   },
   {
      "featureType":"road",
      "elementType":"geometry.stroke",
      "stylers":[
         {
            "weight":"0.49"
         },
         {
            "visibility":"on"
         },
         {
            "saturation":"0"
         },
         {
            "color":"#9a9a9a"
         },
         {
            "gamma":"1.55"
         },
         {
            "lightness":"0"
         }
      ]
   },
   {
      "featureType":"road.highway",
      "elementType":"geometry.fill",
      "stylers":[
         {
            "color":"#c280a3"
         }
      ]
   },
   {
      "featureType":"road.arterial",
      "elementType":"labels.icon",
      "stylers":[
         {
            "visibility":"off"
         }
      ]
   },
   {
      "featureType":"transit",
      "elementType":"all",
      "stylers":[
         {
            "visibility":"off"
         },
         {
            "color":"#a73636"
         }
      ]
   },
   {
      "featureType":"water",
      "elementType":"all",
      "stylers":[
         {
            "color":"#cfd0d0"
         },
         {
            "visibility":"on"
         }
      ]
   }
]
function initMap() 
{
   
   ...

   const mapOptions = {
      ...
      styles: [
         // our snazzy maps JSON code
      ]
   }

   ...

}

And we are done! πŸŽ‰ If you’ve made it this far, I commend thee. I hope this tutorial was useful in learning how to display a stylish custom Google Map on your website.

11. Complete Commented Code & Conclusion

Pat yourself on the back if you’ve made it this far!

We’ve gone through a numbers of steps to create a beautiful custom Google map that you can use on your personal website or client websites, that I’m sure, not only yourself will appreciate, but your end-users.

You can either copy the code below or fork it from Github.

  • index.htm
  • main.js
<!doctype html>
<html>

   <head>

      <link rel="stylesheet" id="uniform-css" href="/wp-content/themes/feh-v1/fonts/fonts.css" type="text/css" media="all">
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
      <title>How to build a stylish Google Map with custom location markers</title>

      <style>

      * { padding: 0; margin: 0; }
      html, body { height: 100%; }
      body { display: flex; }

      #google-map {
         margin: 0 auto 0 auto;
         border: 1px solid #ccc;
         width: 700px;
         height: 500px;
         align-self: center;
      }
      .feh-content * {
         font-family: 'uniform';
      }
      .feh-content h3 {
         font-weight: 500;
         margin-bottom: 10px;
      }
      .feh-content p {
         font-style: normal;
         line-height: 16px;
         font-weight: 400;
      }
			
      </style>

   </head>

   <body>
      <div id="google-map"></div>		
   </body>
         
   <script defer src="https://maps.googleapis.com/maps/api/js?key=YOURAPIKEY&callback=initMap"></script>
   <script src="main.js"></script>

</html>
function initMap() 
{

   /** 
   * Create array of locations
   */
   const markers = [
      {
         locationName: 'Crumbs & Dollies',
         lat: 51.512222624233566,
         lng: -0.13840734189018739,
         address: '1 Kingly Ct,<br> Carnaby,<br> London,<br> W1B 5PA'
      },
      {
         locationName: 'Rinkoff Bakery',
         lat: 51.52026231452749,
         lng: -0.052815725337595015,
         address: '222-226 Jubilee St,<br> London,<br> E1 3BS'
      },
      {
         locationName: 'Comptoir Gourmand Bermondsey',
         lat: 51.500874447971604,
         lng: -0.0819699,
         address: '96 Bermondsey St,<br> London,<br> SE1 3UB'
      },
      {
         locationName: 'Bageriet',
         lat: 51.51195028807007,
         lng: -0.12619283058494118,
         address: '24 Rose St,<br> London,<br> WC2E 9EA'
      },
      {
         locationName: 'Ole & Steen',
         lat: 51.50635804760832,
         lng: -0.017434353136203003,
         address: 'CR34 Crossrail Pl,<br> London,<br> E14 5AR'
      }
   ];

   /** 
   * Create custom marker icon
   */
   const fehMarker = 'https://www.frontendhero.dev/wp-content/uploads/2023/03/feh-marker.png';

   /** 
   * Initially center map on London, UK
   */
   const centerMap = {
      lat: 51.5114675,
      lng: -0.1266686
   }

   /** 
   * Create map options for our map
   */
   const mapOptions = {
      center: centerMap,
      zoom: 12,
      disableDefaultUI: true,
      styles: [{
            "featureType": "administrative",
            "elementType": "all",
            "stylers": [{
               "visibility": "on"
            }]
         },
         {
            "featureType": "administrative",
            "elementType": "labels.text.fill",
            "stylers": [{
               "color": "#444444"
            }]
         },
         {
            "featureType": "landscape",
            "elementType": "all",
            "stylers": [{
               "color": "#f3f3f3"
            }]
         },
         {
            "featureType": "landscape.natural",
            "elementType": "all",
            "stylers": [{
               "color": "#cccccc"
            }]
         },
         {
            "featureType": "poi",
            "elementType": "all",
            "stylers": [{
               "visibility": "off"
            }]
         },
         {
            "featureType": "road",
            "elementType": "all",
            "stylers": [{
                  "saturation": "0"
               },
               {
                  "lightness": "0"
               },
               {
                  "visibility": "simplified"
               }
            ]
         },
         {
            "featureType": "road",
            "elementType": "geometry.stroke",
            "stylers": [{
                  "weight": "0.49"
               },
               {
                  "visibility": "on"
               },
               {
                  "saturation": "0"
               },
               {
                  "color": "#9a9a9a"
               },
               {
                  "gamma": "1.55"
               },
               {
                  "lightness": "0"
               }
            ]
         },
         {
            "featureType": "road.highway",
            "elementType": "geometry.fill",
            "stylers": [{
               "color": "#c280a3"
            }]
         },
         {
            "featureType": "road.arterial",
            "elementType": "labels.icon",
            "stylers": [{
               "visibility": "off"
            }]
         },
         {
            "featureType": "transit",
            "elementType": "all",
            "stylers": [{
                  "visibility": "off"
               },
               {
                  "color": "#a73636"
               }
            ]
         },
         {
            "featureType": "water",
            "elementType": "all",
            "stylers": [{
                  "color": "#cfd0d0"
               },
               {
                  "visibility": "on"
               }
            ]
         }
      ]

   }

   /** 
   * Add map to div, and include above map options
   */
   const map = new google.maps.Map(document.getElementById("google-map"), mapOptions);

   /** 
   * Create InfoWindow object 
   */
   const infoWindow = new google.maps.InfoWindow({
      minWidth: 200,
      maxWidth: 200
   });

   /** 
   * Create bounds object
   */
   const bounds = new google.maps.LatLngBounds();

   /** 
   * Loop through all markers
   */
   for (let i = 0; i < markers.length; i++) 
   {

      /** 
      * Create new markers
      */
      const marker = new google.maps.Marker({
         position: {
            lat: markers[i]['lat'],
            lng: markers[i]['lng']
         },
         map: map,
         icon: fehMarker,
         animation: google.maps.Animation.DROP
      });

      /** 
      * Function that will create new info windows with info from markers array/objects
      * and click events to open them
      */
      function createInfoWindows() 
      {
         const infoWindowContent = `
            <div class="feh-content">
               <h3>${markers[i]['locationName']}</h3>
               <address>
                  <p>${markers[i]['address']}</p>
               </address>
            <div>
         `;

         google.maps.event.addListener(marker, "click", function() {
            infoWindow.setContent(infoWindowContent);
            infoWindow.open(map, marker);
         });
      }
      createInfoWindows();

      /** 
      * Recenter map when an info window is closed
      */
      infoWindow.addListener('closeclick', function() {
         map.fitBounds(bounds);
      });

      /** 
      * Fit all of our markers on the map, neatly
      */
      bounds.extend(new google.maps.LatLng(markers[i]['lat'], markers[i]['lng']));
      map.fitBounds(bounds);
   }

}

If this tutorial has helped you, I wouldn't say no to a coffee as a tip β˜•οΈ

Buy Me a Coffee at ko-fi.com

Leave a Reply

Your email address will not be published. Required fields are marked *