Google Maps API 3 – InfoWindows
Google Maps API 3
- Google Maps API 3 – The basics
- Google Maps API 3 – Map settings
- Google Maps API 3 – Markers
- Google Maps API 3 – InfoWindows
- Google Maps API 3 – Mobile devices
Using InfoWindows is a brilliant way to display information about a certain location. Since they provides you with a space to put text or whatever HTML you please, they can be used in very interesting ways. In this article, which is the fourth in a series about Google Maps API 3, I will show you how to make good use of this great feature.
The InfoWindow object
The InfoWindow object will open an InfoWindow somewhere on a map. It looks like a speech bubble and the tip of its stem typically points to a certain object on the map. Often it’s pointing at a marker, but it doesn’t have to be. It can point at any other object or any coordinate on the map.
The object resides in the google.map.InfoWindow namespace and takes an optional argument which is options. Options is an object literal in which you can define all the properties for the InfoWindow. This means that you can create an empty InfoWindow object for later use, but most of the time you’ll probably want to fill it with some sort of content right away. To fill it with content you’ll need to use the property content. It can be set either on creation of the object or afterwards using the setContent() method. It can be either a text string, a string containing HTML, or a reference to an existing HTML node.
Setting the scene
We will start with a map with one marker on it. If you don’t know how to create a map and add markers to it, I suggest that you read the previous articles in this series first.
For those of you that are already familiar with the concepts, here’s the code for creating a map and adding a marker to it:
// Creating an option object for the map
var options = {
zoom: 7,
center: new google.maps.LatLng(56.83, 15.16),
mapTypeId: google.maps.MapTypeId.ROADMAP
};
// Initializing the map
var map = new google.maps.Map(document.getElementById('map'), options);
// Creating a marker
var marker = new google.maps.Marker({
position: new google.maps.LatLng(56.8848, 14.7730),
map: map,
title: 'My workplace'
});
This will result in a map that looks like this:

Adding an InfoWindow
Now that we have the scene set, lets add an InfoWindow to it. In this example we will instantly fill the InfoWindow with some content, in this case the classic text string “Hello world”:
// Creating an InfoWindow object
var infowindow = new google.maps.InfoWindow({
content: 'Hello world'
});
Showing the InfoWindow
We have now created an InfoWindow object but not yet added it to the map. To make it appear we have to first open it and that’s done with its method open(). This method takes two arguments: the map object which it will be added to and optionally an anchor where it will point to. The anchor must be an object on the map that exposes a position property. As of now this will probably be a marker.
If you don’t pass on the second argument you must provide the InfoWindow object with a position. This is done with either the attribute position in options or via its setPosition() method. In this example however, we will pass our marker as the second argument so that the InfoWindow will point straight at it.
infowindow.open(map, marker);
Now the InfoWindow will be visible on the map and will look like this:

Note that the default behavior of the map is that it pans so that all of the InfoWindow is visible. This behavior can be overridden by setting the property disableAutoPan to false.
Adding a click event
As of now our InfoWindow is automatically opened when our map loads. Most of the time we want it to open when something is clicked and that’s exactly the functionality we’re going to add next. We’re going to add a click event to the marker so that when it’s being clicked the InfoWindow will open.
To add an event to the marker we will need to use the addListener() method found in google.maps.event. This method takes 3 arguments, the first one being the object it will be attached to, in this case the marker. The second argument defines what kind of event we want to add, in this case a click event. The third argument is a function which will be called when the event is being triggered. In this case we will use an anonymous function and we will move the code that opens the InfoWindow inside it.
Doing that the code will look like this:
google.maps.event.addListener(marker, 'click', function() {
infowindow.open(map, marker);
});
Now, when we load our page the InfoWindow will not be visible until we click the marker. Then it will pop up.
Using multiple InfoWindows
You may have noticed that we create the InfoWindow outside the click event of the marker. Perhaps you’re thinking that we might as well could have put all of the code regarding the InfoWindow inside it. But there’s a good reason for not doing that. By creating the InfoWindow outside the event handler, we ensure that there only exists one InfoWindow at a time. If we had put the code for creating the InfoWindow inside the event handler we would have created a new InfoWindow each time the marker was clicked. Leaving us with several identical InfoWindows on top of each other.
Now there are ways to deal with this. We could for example check if the InfoWindow existed before creating it, but by creating it only once we completely avoid the problem all together.
If you’ve been programming in version 2 of the Google Maps API you’ll notice a significant difference here. In the old API we could only have one InfoWindow at a time, but now we can have several. Because of this we have to change how we think about them. There might be occasions when we want to display several of them at once, but often we will only want to display them one at a time.
More control over the Info Window
There are some other properties that you can add to options for added control of the InfoWindow. I’ve already mentioned content which defines what will be displayed inside of it and position which in lack of an anchor defines the position of the InfoWindow. But here’s all of the properties available for controlling the look and behavior of the InfoWindow:
content
This property defines the content of the InfoWindow. It can be either plain text, HTML or a reference to an existing HTML element. The InfoWindow will automatically adjust its size to fit the content.
disableAutoPan [boolean]
If set to true the map is no longer automatically panned to fit the InfoWindow. Default value is false.
maxWidth [number]
Sets the maximum width of the InfoWindow in pixels. It must be set before the InfoWindow is opened.
Another way of controlling the size of the InfoWindow is to add HTML with certain dimensions to it. This way you can control its size from you CSS.
pixelOffset [size]
If position is used to place the InfoWindow, pixelOffset defines how far away from this point the window should be positioned.
position [LatLng]
Defines the position the InfoWindow should be pointing at. If an anchor (the second argument of the open() method is set, it will override this property.
zIndex [number]
When displaying multiple InfoWindows at the same time, this property will determine the stack order of those.
Live demo
Check out the Live Demo showing the example used in this article.
Hopefully this article has provided you with a basic understanding of how to use InfoWindows in your maps but there are a lot more that can be done with them. They still lack a lot of the functionality found in the old API, like displaying a detail map inside it or having tabbed content. Some of these features will probably never find its way into the new API but fortunately it’s quite easy to build this functionality yourself. Keep your eyes open for my upcoming book where I will explain how to do some of this stuff.
Further reading
For more information about the InfoWindow object, check out the Official Google Maps Reference. You might also want to check out the section in the documentation about Overlays.
My Google Maps book
If you found this article useful you might be interested in my book Beginning Google Maps API 3. It covers everything you need to know to create awesome maps on your web sites. Buy it on Amazon.com

I’m trying to loop through an array of infoWindows and add an event listener to each of them. However, you can’t pass
good tutorial
could u plz tell us a littlebit about how to customize the infowindow?
I appreciate the initiative from google to enable us customise maps. However i have a problem i want to solve inside the info windows i have created.
I have added a couple of links in each info window. But now i need to maximise each info window when a user clicks on each link after which they may minimize and return to summary info window or close.
Hello, thanks a lot for your articles, they have helped me a lot.
I am currently working on my university thesis which uses Google Maps API v3 and I have a problem with the info windows.
I am using a php loop creating a marker for each child in an xml file with info about the Greek Universities:
Placemark as $institution) {
$uni_name = htmlspecialchars($institution->name);
$uni_latlong = htmlspecialchars($institution->Point->coordinates);
?>
var marker = new google.maps.Marker({
position: new google.maps.LatLng(),
map: map,
title: ”,
clickable: true
});
var infowindow = new google.maps.InfoWindow({
content: ‘Hello world’
});
google.maps.event.addListener(marker, ‘click’, function() {
infowindow.open(map, marker);
});
As it is, the info window appears only if you click the last marker the loop created. Of course this is due to using the same name for the marker variable on every cycle. How do you suggest I solve this? I am VERY confused.
Thanks in advanced,
Teo
Teo: Like you said yourself, just give each marker and infowindow variable a unique name (marker1, marker2, etc) and it will work for you.
Glad to hear that my articles have helped you! That is always nice to hear!
I will make an array
Have the pride of knowing that not only you are AWESOME but you are helping me get my degree
I will send you the full code once I’m done for the lulz
Ok, one more question and I’m covered (I hope). I made all the different infowindows appear, how can I close the others when I click and open a new one?
Tried closeInfoWindow(); in the listener function but it disables all of them…
Teo: The easiest way to do this is to just have one instance of the InfoWindow object that you reuse over and over again. That way when you click a new marker the infoWindow is “moved” from where it’s currently at, to point at the new marker.
Use its
setContentmethod to load it with the correct content.Hi Gabriel,
Thanks A LOT for this article, understanding how the new InfoWindow works is very helpful, and makes great sense.
I just thought I’d ask, do you know if the tabbed InfoWindows from V2 will be implemented anytime soon? Or perhaps is it implemented but just not yet documented?
Cheers!
John: As far as I know tabbed InfoWindows is not implemented in v3. Whether or not it’s going to be implemented I don’t know.
Hello,
I like the way that V3 is implemented in JS, but I have problem to change the layout of InfoWindow, because it has no longer the second parameter (ID) like in V2
marker.openExtInfoWindow(map, ElementID,…).
And now I can not make any CSS to change the layout of InfoWindow.
When I search the code I found that the top tag of InfoWindow is so max. what I can do is define some style for this class and child tags, but there is no diffenrence between the top left and top right corner divs (no id or class).
Any suggestions how to solve this problem or should I better return to V2 coding?
Is it possible to have a infowindow connected to a polygon?
Dick: That’s is entirely possible.
Does V3 support tabbed InfoWindow? I use openInfoWindowTabsHtml in V2. I hope V3 has the similar feature.
Hwy man, I am trying to do the thing you said but I cannot
Could you make the following comments code that would work?
function markerselect(id) {
map.panTo(markers[id].position);
// if tempinfowindow exists close it or whatever
// if it does not exist make it have the contents of infowindows[id]
tempinfowindow.open(map, markers[id]);
}
Thanks in advanced
Hello again,
I tried to link an information window to a polygon in the same manner as for a marker, but failed. Can you see here http://liftstol.se/test.htm what I’m doing wrong?
Thank you in advance!
// Dick
Does API V3 will let us to use tabbed infowindows ? I really need this !
Does the v3 InfoWindow not have some sort of ‘onClose event’? I’m aware of the ‘closeclick’ event but I want to trigger a function whenever the infowindow is closed by any means (clicking the x or programatically).
Dad00: No there’s currently no tabbed InfoWindows in API 3. There are however different ways of implementing 3d party tabs in an InfoWindow. Check out this discussion in the Google Maps JavaScript API v3 group.
Jason: There’s no onClose event to my knowledge. I think you are right there are definitely cases where an onClose event would be called for.
Can we call Javascript from inside (the content) of an infowindow?
Hi Gabriel,
I am new to Java and I am trying to run this map with infowindow going away after you click another. If I am creating infowindow new every time its works but only keeping all the windows. my issue seems to be ‘infowindow.setcontent(itext);’
please help me out, I am sure it is just a little thing.
Thank you.
Alfred
var infowindow;
function initialize() {
var myOptions = {
zoom: 6,
center: new google.maps.LatLng(-42.945397, 171.565676),
mapTypeId: google.maps.MapTypeId.ROADMAP
}
var map = new google.maps.Map(document.getElementById(“map_canvas”),
myOptions);
setMarkers(map, days);
infowindow = new google.maps.InfoWindow({ content: “blabla”});
}
var days = [
['Day 1: Kaikoura', -42.416667, 173.683333,1,' Click here for Wikipedia'],
['Day 2-4: Nelson Lake', -41.819167, 172.8375, 2,' Click here for Wikipedia'],
['Day 5: Paparoa ',-42.083333, 171.5, 3,' Click here for Wikipedia'],
['Day 6: Okatiro ',-43.2, 170.216667, 4,' Click here for Wikipedia'],
['Day 7: Franz Josef Glacier', -43.466997, 170.191528, 5,' Click here for Wikipedia'],
['Day 8-9: Queenstown ',-45.031111, 168.6625, 6,' Click here for Wikipedia'],
['Day 10: Hollyford Track ',-44.7350590018039,168.208030237917 , 7,' Click here for Wikipedia'],
['Day 11: Milford Sound ',-44.675, 167.929444 , 8,' Click here for Wikipedia on Milford Sound'],
['Day 12: Lake Pukaki ',-44.116667, 170.166667, 9,' Click here for Wikipedia on Lake Pukaki'],
['Day 13: Mt Cook National Park ',-43.733333, 170.1 , 10,' Click here for Wikipedia on Mount Cook National Park'],
['Day 14: Christchurch ',-43.53, 172.620278 , 11,' Click here for Wikipedia']
];
function setMarkers(map, locations) {
// Add markers to the map
for (var i = 0; i < locations.length; i++) {
var beach = locations[i];
var myLatLng = new google.maps.LatLng(beach[1], beach[2]);
var marker = new google.maps.Marker({
position: myLatLng,
map: map,
title: beach[0],
zIndex: beach[3]
});
attachSecretMessage(map,marker,beach[4]);
}
};
function attachSecretMessage(map,marker,itext) {
// var infowindow = new google.maps.InfoWindow(
// { content: itext});
google.maps.event.addListener(marker, 'click', function() {
infowindow.setcontent(itext);
// infowindow.setPosition(marker);
infowindow.open(map,marker);
});
};
//function attachSecretMessage(map,marker,itext) {
// var infowindow = new google.maps.InfoWindow(
// { content: itext
// });
// google.maps.event.addListener(marker, 'click', function() {
// infowindow.open(map,marker);
// });
//};
hello; ok we can see infowindows when we clicked the marker and we can add text for example “hello world”. my question is how can i add photo or image into infowindow. this mean when i click the marker infowindow is opening and i can see the photo which i add it before i see alot of site like this. please help me to add photo to infowindows
thnx a lot..!
I think I speak for most people, that one of the richest features of the bespoke development of GoogleMaps API was TABS.
Pamela’s version is functional, but visually non appealing with a lot of lost space.
Personally… I’ll be sticking with v2 (reluctantly).
Martel: It’s really easy to add photos since you can add any html you like instead of the text hello world. Just add an <img> as the value for the content property like this:
var infowindow = new google.maps.InfoWindow({
content: '<img src="url/to/your/image/" alt="" />'
});
Todd: I agree with you that InfoWindow tabs is a very appealing feature in API v2. Start an uproar in the API forum, and maybe the API team will add it in v3!
You could also add a feature request. The API is still in Beta so everything is possible.
Thank you for this tutorial. It was really helpful.
I just want to share something.
I created a markerArray variable to store the markers in the map. I also had the infoArray variable to store all the associated infowindow. (All these were done using PHP and mySql).
I tried to loop through the action listener so as to reduce the code. But I encountered the same problem as stated above. The infowindow is displayed only for the last marker. But I found a solution to this problem. And that is by adding a function inside the loop itself.
After adding all the markers from the database, I looped the markerArray and called the function addInfo with the parameters markerArray[x],infoArray[x],map.
Inside this function I added the addListener. And to my surprise, it worked.
Lastly, thanks for this tutorial. It was really helpful.
Infowindow doesn’t really look nice in a small map, basically the rounded corners and the balloon tip takes so much space. Is there a way to use the smaller square balloon in V3?
Although there are available examples to replace the infowindow, but most of the solutions fixed size images which are not as flexible as the current infowindow.
Hope you could share some of your tricks to solve this. Thanks!
Maybe I am slow…..but I can’t seem to get the concept of what I need to add for multiple markers. Can someone provide a link with an example? Thank you very much!
Hi,
I’m not a JavaScript man but can recognise simple statements and repeat them to expand on existing code. Can you direct me to a sample where I can add multiple custom markers plus an info window for each marker. I have found all this individually but I’m not able to combine the features.
I’ll be internally grateful after devoting 3 days on this…
Cheers,
Rene
@Rene: If you have not found an answer to your question, probably you can look into complex overlay example. Just play with the image and location a little then add some extra info with the location then you should have your multiple custom markers. Finally follow the example above to add in the infowindows. Hope this helps
I encountered the same problem as others when using a for loop to create events for markers. Perhaps it is an issue with the API, but regardless, I remember from my Java days that funny things can happen when references to things are passed around and you don’t know what exactly is being done.
But anyhow, I was speculating that with the unwanted behavior we are all getting the event thingy-ma-bobber must work as follows:
1. You register the event
2. Something somewhere stores that you registered an event to that item
3. For the action that it takes upon click it stores a function pointer
*4.* For the arguments to this function, it stores a pointer to the arguments.
This means that when you put the function in a for loop as so:
for(var i=0; i<arr.length;++i){
google.maps.events.addListener(arr[i],'click', function(){
ActionFunction(arr[i]);
});
}
It must be the case that ActionFunction is still in the same scope, meaning that it still points to the same function with the same argument. This means that every time the for loop iterates, it gives it a pointer to the same function with the same arguments, and you only have the affect of changing what those arguments (which are just boxes that hold pointers) point to. Therefore, you get what was pointed to by those parameters on the last iteration. And thus, with the solution that Ricky came up with, it calls a regular function first, meaning that pointers to the parameters of this function are pushed on the stack on each iteration and the function is called. Each time the event is registered the last even registration is completely out of scope, and thus the API is not able to take whatever shortcut it did before.
Note: This is just an attempt for me to rationalize the behavior of the API and is complete speculation on my part. I actually have no clue and am in fact not fully satisfied with this explanation as I feel that there is a whole in my logic somewhere…
So, just curious, have you ever encountered an issue like this when using the V3 API? For those of you who used the version two API's, has anyone encountered this issue? I am just wondering if this is the intended behavior, because it seems so unintuitive…
Hi,
This is a great tutorial! I was able to implement getting multiple markers on my map, but I’m having problems with the InfoWindow passing the correct text to the correct marker. It basically picks the last text that gets presented, and passes it to any marker that is clicked. Javascript is not my forte, and I have it running as echo statements in PHP. Can somebody take a look at this code and help me figure out how to make this work so that each marker gets the correct text? Thanks!
while($row = mysql_fetch_array($result))
{
echo “var marker = new google.maps.Marker({\n”;
echo ” position : new google.maps.LatLng(” . $row['latitude'] . “,” . $row['longitude'] . “),\n”;
echo ” map : map,\n”;
echo ” icon : ‘images/photo.png’\n”;
echo “});\n”;
echo “var infowindow = new google.maps.InfoWindow({\n”;
echo ” content : ‘” . addslashes($row['description']) . “‘\n”;
echo “})\n”;
echo “google.maps.event.addListener(marker, ‘click’, function() {\n”;
echo ” infowindow.open(map, marker);\n”;
echo “})\n”;
}
This code gives the following results :
var marker = new google.maps.Marker({
position : new google.maps.LatLng(32.396989,-111.004427),
map : map,
icon : ‘images/photo.png’
});
var infowindow = new google.maps.InfoWindow({
content : ‘Hill located in West Lambert Lane Park. Great 360 views of Tucson and the surrounding area.’
})
google.maps.event.addListener(marker, ‘click’, function() {
infowindow.open(map, marker);
})
var marker = new google.maps.Marker({
position : new google.maps.LatLng(32.420879,-110.982298),
map : map,
icon : ‘images/photo.png’
});
var infowindow = new google.maps.InfoWindow({
content : ‘Another hillside location in Oro Valley. Great views to the west for storms in the valley.’
})
google.maps.event.addListener(marker, ‘click’, function() {
infowindow.open(map, marker);
})
Which is good, but only the last content text gets passed to any marker I click on. Thanks for the look!
Mark
Hi there,
I have generated a map with a bunch of markers and ifnoboxes that contain text/addresses etc that are visible. What I am struggling with is the format to add photographs. I have added a field in the phpmysql database (mediumblob) but am unsure wether I provide the url for the picture or what to do next…I am a bit of a noob at this so any help would be great.
Many thanks
Sean
I have a map with mutiple markers and info windows and found your tutorial instrumental in getting this working. I have a sidebar with a list of the places identified and would now like to be able to link to the information window.
My javascript is very basic, how can I do this?
My map is http://www.planetengineering.com.au/maptest/index.html
Bronwyn
Hi Gabriel,
anyway a great tutorial, well done.
Can you please clarify how manage a lot of infowindows so that a behaviour is the same as it is in version 2 ?
If I use another variable for each marker (infowindow and content) then I can see another content for each marker but with click on another infowindows the previous one is still open.
If I use one varible of marker, infowindow and content for each marker than the window’s closing work well but I can see only one content.
@mirekh
I think you’re close. You can have multiple variable of marker but you must declare a global infowindow variable. But the the trick is to put the declaration of the infowindow inside a function like this:
////////////////////////
var iw; // Global InfoWindow
var map; // Global Map
function initialize() {
// map declarations here
iw = new google.maps.InfoWindow();
// for loop
var mymarker = new google.maps.Marker({position:myLatLng,map:map});
createMyInfoWindow(mymarker,"my content");
// end of for loop
}
function createMyInfoWindow(mymarker,mycontent) {
google.maps.event.addListener(mymarker, 'click', function(){iw.setContent(mycontent);iw.open(map, mymarker);});
}
////////////////////////
This is similar to what @Alfred Laggner posted above, although simpler.
Hope this helps!
Hello,
I couldn’t get the multiple markers, multiple info windows to work, no matter what was said above.
When in a loop:
for (var i = 0; i < markers.length; i++) {
var marker = markers[i];
var infowindow = new google.maps.InfoWindow({
content: "holding..."
});
google.maps.event.addListener(marker, 'click', function () {
infowindow.open(map, maker);
});
}
This always showed the last marker that was bound to map so the info window always appeared on the last marker. Bit of a problem really.
After reading http://bit.ly/aEtHk1 it showed me the mistake everyone here has made and the actual solution!
for (var i = 0; i < markers.length; i++) {
var marker = markers[i];
var infowindow = new google.maps.InfoWindow({
content: "holding..."
});
google.maps.event.addListener(marker, 'click', function () {
infowindow.setContent(this.html);
infowindow.open(map, this);
});
}
Changes in bold. As you have all seen the event fires for each marker, but as you were calling infowindow.open(map, marker) javascript engine’s memory location thingymabob (not good with names) held the last reference to marker. But you had passed in the marker to the event, so by calling this in place of marker, you get what you are looking for.
Hope this helps someone out.
Colin
[...] http://www.svennerberg.com/2009/09/google-maps-api-3-infowindows [...]
Hello,
I am able to display content on Info Window by creating InfoWindow object, however i am unable to get default link(e.g. Directions, Search nearby, Saveto & More link).
I am unable to find any method of InfoWindow object by using that i can show the above utility link in InfoWindow.
Thanks,
Rajeev Jha
The code given by Colin Wiseman worked for me.
Thanks!
@Colin Wiseman
“html” must be setted in markes:
After, ‘content: “holding…”‘, add ‘html: “content”‘
for (var i = 0; i < markers.length; i++) {
var marker = markers[i];
var infowindow = new google.maps.InfoWindow({
content: "holding…",
html: "content"
});