7 days of unlimited WordPress themes, plugins & graphics - for free!* Unlimited asset downloads! Start 7-Day Free Trial
  1. Web Design
  2. Google Maps API

How to Build a Custom Google Map With Stylish SVG Markers

Scroll to top
Read Time: 10 mins

In this new tutorial, we’ll use the Google Maps JavaScript API and learn how to create a custom map, with multiple stylish markers indicating some of the Adobe office locations.

As usual, to better understand what we’re going to build, look at the demo page. Be sure to click either on the locations or the map markers.

Custom Google Map Demo

Take a look at this fully interactive custom Google map we’re going to create.

custom google map screenshotcustom google map screenshotcustom google map screenshot

Project Structure

For this exercise, our custom Google Map demo will live on GitHub (not on CodePen). Here’s the project structure:

1. Scaffolding the Project

Before we start creating our project (that will look like a mini app) there are a few things that we have to take into consideration.

Grab a Google Maps API key

As a first and mandatory thing, we should get a  Google Maps API key. To do so, we need to follow these instructions and set up a project in the Google Cloud Console with the Maps JavaScript API enabled.

For this demonstration, we’ll borrow an API key from an old yet still popular series called The Google Maps API For Designers. There’s also an associated demo from where we can extract the API. 

This demo API key has usage limits! Make sure to register for your own API key and replace the one in the example.

Last but not least, as soon as you set up such a project in the Google Cloud Console, it’s always wise to restrict the associated API. For example, you might have a single project and an API that you share across all your website clients. In such a case, you can restrict the API requests to specific websites.

How to restrict an API key on certain websitesHow to restrict an API key on certain websitesHow to restrict an API key on certain websites

Grab Some Data

To create the markers and make our project as realistic as possible, we’ll need some real-world data. With this in mind, as previously mentioned, we’ll take 13 of the Adobe office locations and pin them on our map.

As we’ll see later, each location needs to include its latitude and longitude. As this info isn’t available on Adobe’s contact page, we’ll use the LangLong.net website to retrieve their coordinates. Some of the coordinates might not be perfectly accurate, but you get the point.

Grab Some Icons

To enhance the demo appearance, we’ll need some icons.

Envato Elements provides hundreds of different map and navigation icons for our needs. In this case, we’ll go with an icon set that follows a filled line style. As we saw from the project structure, the selected SVG icons will live inside the img folder.

The icon pack that we're going to useThe icon pack that we're going to useThe icon pack that we're going to use

Here are the SVG icons we’ll use in our project:

svg icons for custom google mapsvg icons for custom google mapsvg icons for custom google map

Include Bootstrap Files

Lastly, although not required, to speed up the development process we’ll also include Bootstrap in our project by following the CDN approach, as described on this page.

2. Define the Page Markup

Now that we have everything set up, let’s look at our markup.

Required Files

Below you can see the starting markup with all the required Bootstrap files, our files, and the script tag for the Maps JavaScript API:

Just take a look at the script tag for the Maps JavaScript API.  You’ll see two attributes:

  • The src attribute includes the base call to the Maps JavaScript API along with three parameters: two required and one optional. The required key parameter stores our API key as retrieved from the Google Cloud Console. The optional language parameter determines the map’s language (location names, labels, etc.). The required callback parameter defines the name of the global function that will fire once the Maps JavaScript API finishes its load.
  • The async parameter tells the browser to asynchronously download and execute the script. 

Custom Google Map Layout

Before having a closer look at the page elements, let’s discuss the layout requirements.

  • On mobile screens (<768px), the layout will be like this:
The mobile layoutThe mobile layoutThe mobile layout
  • On medium and large screens (≥768px), there will be two equal-width columns:
The desktop layoutThe desktop layoutThe desktop layout
  • In each case, the map will cover the window height. 

Here’s the associated markup filled with Bootstrap helper classes:

Most importantly, notice two things:

  • Each location link, which represents an Adobe location, comes with the data-index attribute. Keep this attribute in mind, as we’ll use it later on.
  • There’s an empty element with the map ID. This will include the map contents and will be generated through JavaScript. 

3. Add the JavaScript

At this point, we’re ready to build the core functionality of our custom Google Map project. Let’s do it!

Store Locations

We captured the locations in the markup, but we also need them in JavaScript. So, let’s store them under an array like this:

Keep in mind that we preserve the order in which the locations appear both in the markup and object. A location with the data-index="0" in the markup denotes that the same location should be in the first place of the pins array.

Note: in a real-world scenario, there would probably be a backend language to manage all locations in one place. For example, if you’re familiar with WordPress and the ACF PRO plugin, you’ll probably have a flexible content or a repeater field where you put all locations. Inside it, there will be extra fields for managing the location details. Especially for grabbing the coordinates of each location, you can have a Google Map field. Then, via the wp_localize_script() you’re able to pass the locations in the JavaScript and build an object similar to the one we have here.

Initialize Custom Google Map

Coming up next, we’ll initialize the map through the initMap() that we showed before. 

Our map will have the following customizations:

  • It’ll be centered in London, UK.
  • It’ll have zoom: 3 to see as many locations as possible by default.
  • We’ll customize its default styles through this tool, but you can always opt for cloud-based map styling. Most notably, we’ll change the default color of the water like this:
Google Maps: custom styles vs default stylesGoogle Maps: custom styles vs default stylesGoogle Maps: custom styles vs default styles

With all the above in mind, here’s the starting body of our function:

Create Google Map Markers

Inside the initMap() function, we’ll also call the createMarkers() function for creating the location markers:

Inside this function, we’ll do the following things:

  • Initialize an info window that will display information about a marker each time someone clicks on it.
  • Replace the default marker icon with a custom SVG one.
custom marker vs default markercustom marker vs default markercustom marker vs default marker
  • Loop through the locations and position them on the map based on their coordinates. Also, make them appear with a DROP animation.
  • Store each marker instance in the markers array. We’ll see why later.

Here’s the function declaration:

Toggle Info Window

Inside the createMarkers() function, we’ll also register a click event for each marker.

Each time a user clicks on a marker, we’ll perform the following actions:

  • Populate the info window’s content with contents associated with this marker thanks to the createInfoContent() function.
  • Set the map’s center based on the coordinates of this marker.
  • Show the info window.
  • Remove the active class from any associated location link, if any.
  • Find the location link whose index matches the index of this marker and give it the active class. This will give the target link a blue background color.
The active stateThe active stateThe active state
  • Smooth scroll to the corresponding location link.

Populate Info Window

As we said, the job of the createInfoContent() function will be to feed the info window with the contents of the clicked marker. 

We’ll use straightforward markup to display the contents of each marker. Given that some locations don’t always have all the details, we’ll apply some checks to ensure that our markup won’t be bloated.

How the info window will look likeHow the info window will look likeHow the info window will look like

Here’s the function declaration:

We discussed what should happen when a marker is clicked. But we also need to apply some functionality when the opposite happens. In other words, we want to ensure that each time a user clicks on a location link, the corresponding marker will be clicked.

Another function, the showLocations() one, will be responsible for handling this functionality. This will also live inside the initMap() function.

So, each time a location link is clicked, we’ll perform the following actions:

  • Cancel its default behavior.
  • Remove the active class from any location link, if any.
  • Add the active class to this link.
  • Smooth scroll to the map.
  • Find the marker whose index matches the index of this link and trigger its click event. We’re able to target the specified marker because we’ve stored it in a previous step inside the markers array.

Here’s the function definition:


And we’re done! This was quite a long journey, but I hope that you enjoyed it and that it has helped enhance your skills regarding the Google Maps JavaScript API.

Once again, don’t forget to put your own key for live project testing! Here’s the project link

Things don’t stop here. We can continue enhancing/extending this project by doing a number of things, for instance:

  • Put into table marker clusters for grouping markers. This is a nice addition, especially for cases where there are a lot of markers.
  • Make this project dynamic by using WordPress and ACF PRO, as explained in a few sections above. Depending on how this project goes, I’ll probably come back with such a tutorial in the future :)
  • Restrict the map boundaries to avoid showing a gray area during dragging or zooming out.
The gray area that appears during dragging and zooming outThe gray area that appears during dragging and zooming outThe gray area that appears during dragging and zooming out

As always, thanks a lot for reading!

Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Web Design tutorials. Never miss out on learning about the next big thing.
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.