Inline SVG as Google Maps marker

For a Google Maps based project with a lot of similar markers, I was looking for a way to reduce redundancy for these marker images. The marker images look all the same, only differing in the background color. Also there is a gradient and a drop shadow included. That would be a perfect use case for a SVG symbol sprite!

The problem

Sadly the Google Maps API doesn’t allow us to use a SVG sprite as a marker image. No matter what you try – the <use> method or specifying an external file like markers.svg#my-icon – the marker won’t show up on the map.

The solution

When I stumbled across Fun with SVG: Embedding in CSS, an article explaining how to embed an SVG file in CSS, I got interested. Will that work with the Maps API, too? Indeed – it does work!

new google.maps.Marker({
  position: myLatlng,
  map: map,
  icon: {
    anchor: new google.maps.Point(16, 16),
    url: 'data:image/svg+xml;utf-8, \
      <svg width="32" height="32" viewBox="0 0 32 32" xmlns=""> \
        <path fill="red" stroke="white" stroke-width="1.5" d="M3.5 3.5h25v25h-25z" ></path> \

Notice that you can use line breaks, when you escape them.

The Maps API doesn’t like special characters (# especially), though. It doesn’t render the marker at all when that character is somewhere in the SVG. Defining a dropshadow via url(#dropshadow) does not work initially. Trick is, to use encodeURIComponent to escape all these characters.

As we have our SVG in JavaScript now, it is easy to construct it dynamically. In the next example the source SVG is in the DOM and loaded via JavaScript as text. For the background I used a placeholder that can be replaced with the actual color value. Notice the gradient and the drop shadow:

See the Pen Google Maps SVG Marker by Robert Katzki (@ro-ka) on CodePen.

A drawback of this solution is having the paths in the DOM or in the JavaScript. Using a plain SVG symbol sprite would be my preferred solution. Still, we keep our code DRY and maintain paths only once.

Update 2016/01/26:

It turned out that this solution does not work in Internet Explorer 11 and below. IE keeps on surprising us.