title: Google Maps API - "google is not defined"
body: <p>This is driving me mad. I have a page which loads a second page containing a google map. The second page works perfectly on its own but it just shows a blank space when it is opened within the first page.</p>
  
  <p>Javscript console gives the message "ReferenceError: google is not defined".</p>
  
  <p>The first (main) page uses this script to load the map page:</p>
  
  <pre><code>$(document).ready(function(){
  $("#maplink").click(function(){
   var txt = $("#mapspace").is(':visible') ? 'See location map' : 'Hide location map';
   $("#maplink").text(txt);
   $("#mapspace").slideToggle(2000, function() {
      $("#mapspace").load("/includes/map_hotel.php?hid=&lt;?php echo $row_hotel['hid'] ?&gt;");
  });
  $('html, body').animate({
      scrollTop: $("#maplink").offset().top
  }, 2000);
  });
  });
  </code></pre>
  
  <p>Then the second page uses this script for the google maps.</p>
  
  <pre><code>      // global "map" variable
        var map = null;
  
  // InfoBox
   var boxText = document.createElement("div");
          boxText.style.cssText = "border:1px solid #3498db;border-radius:5px;margin-top:8px;background:white;padding:5px;";
  
          var ibOptions = {
           content: boxText
          ,closeBoxURL: ""
          ,disableAutoPan: false
          ,enableEventPropagation: true
          ,maxWidth: 0
          ,pixelOffset: new google.maps.Size(15, -50)
          ,boxStyle: { 
           width: "240px"
           }
          };
  
  // global "infobox" variable
    var ib = new InfoBox(ibOptions);
  
  function createMarker(latlng, html) {
      var contentString = html;
  
      var marker = new google.maps.Marker({
          map: map,
          position: latlng,
          icon: "/images/hotel_grey_icon.gif",
          zIndex: 9998
          });
  
      google.maps.event.addListener(marker, 'mouseover', function() {
          boxText.innerHTML = contentString;
          ib.open(map, marker);
          });
        google.maps.event.addListener(map, 'click', function() {
          ib.close(map, marker);
          });
  }
  
  function initMap() {
        var lat = &lt;?php echo $row_hotel['latitude'] ?&gt;;
        var lng = &lt;?php echo $row_hotel['longitude'] ?&gt;;
        var zoom = 10;
    var thisLatlng = new google.maps.LatLng(lat, lng);
    var mapOptions = {
  center: thisLatlng,
  zoom: zoom,
  mapTypeId: google.maps.MapTypeId.ROADMAP,
     streetViewControl: true,
     scaleControl: true,
     zoomControl: true
     }
  
    map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
  
    var hotelContentString = '&lt;div class="thishotel"&gt;&lt;?php echo $row_hotel['hotel_name'] ?&gt;&lt;/div&gt;';
  
    var hotelmarker = new google.maps.Marker({
        position: thisLatlng,
        map: map,
        icon: "/images/hotel_icon.gif",
        zIndex: 9999
    });
  
  // Infobox for this hotel
          var hibOptions = {
           content: boxText
          ,closeBoxURL: ""
          ,disableAutoPan: false
          ,enableEventPropagation: true
          ,maxWidth: 0
          ,pixelOffset: new google.maps.Size(-70, -75)
          ,boxStyle: { 
           width: "140px"
           }
          };
  
    var hib = new InfoBox(hibOptions);
  
        google.maps.event.addListener(hotelmarker, 'mouseover', function() {
          boxText.innerHTML = hotelContentString;
          hib.open(map, hotelmarker);
          });
        google.maps.event.addListener(map, 'click', function() {
          hib.close(map, hotelmarker);
          });
  
  var style_nopoi = [{"featureType": "poi", "stylers": [{"visibility": "off"}]}]; // Styles, removes points-of-interest. Lots of other possibilities.
  map.setOptions({styles: style_nopoi});  // Applies the style to the map
  
  var loadcnt = 0;
        google.maps.event.addListener(map, 'tilesloaded', function() {
          if (loadcnt==0) {
          map.setCenter(thisLatlng); // Seems to fix random centring problem on mobiles
          loadcnt=loadcnt+1;
          }
          });
  
        downloadUrl("/includes/php-to-xml.php?iso=&lt;?php echo $row_hotel['countryisocode'] ?&gt;", function(doc) {
          var xmlDoc = xmlParse(doc);
          var markers = xmlDoc.documentElement.getElementsByTagName("marker");
          for (var i = 0; i &lt; markers.length; i++) {
  
            var lat = parseFloat(markers[i].getAttribute("lat"));
            var lng = parseFloat(markers[i].getAttribute("lng"));
            var point = new google.maps.LatLng(lat,lng);
            var html=markers[i].getAttribute("html");
  
            createMarker(point, html);
          }
  
        });
      }
  </code></pre>
  
  <p>Things I've tried already:</p>
  
  <ol>
  <li><p>I've tried putting a text file in the .load() of the first script to make sure that is working correctly. It is.</p></li>
  <li><p>I've taken care to ensure that all references to other files are relative to the root ie "/includes/php-to-xml.php".</p></li>
  <li><p>I already had to fiddle around with the order of different parts of the script to make it work at all. I've tried putting all the javascript inside the initMap function but that didn't help either.</p></li>
  <li><p>I tried wrapping the entire content of the script in window.onload = function() { but that broke it completely.</p></li>
  <li><p>Originally I was loading the API with async defer and a callback to the initMap function. I've now dropped all that and use body onload="initMap()" instead. The link to the API and a couple of other external scripts (on my server) are all in the body.</p></li>
  </ol>
  
  <p>One final point to clarify: I am running all this on a test server on my own machine.</p>
  
  <p>I bet it's something simple (it always is!) but I can't see what.</p>
  
  <p>EDIT  geocodezip asked for a minimal, complete code. The main page (in minimal form ie irrelevant stuff removed) is</p>
  
  <pre><code>&lt;!DOCTYPE HTML&gt;
  &lt;html&gt;
  &lt;head&gt;
  &lt;meta charset="utf-8" /&gt;
  &lt;meta name="viewport" content="width=device-width, initial-scale=1" /&gt;
  &lt;link rel="stylesheet" href="/css/main.css" /&gt;
  &lt;link rel="stylesheet" href="/css/lightgallery.css" /&gt;
  &lt;/head&gt;
  
  &lt;body&gt;
  
  &lt;!-- Header --&gt;
  &lt;header id="header"&gt;
  &lt;div class="logo"&gt;&lt;a href="index.html"&gt;BEST Small Hotels&lt;/a&gt;&lt;/div&gt;
  &lt;a href="#menu"&gt;Menu&lt;/a&gt;
  &lt;/header&gt;
  
  &lt;!-- Banner --&gt;
  &lt;section id="banner" style="background-image: url(&lt;?php echo '/images/'.$row_hotel['countryisocode'].'/'.$row_hotel['hid'].'/'.$row_hotel['mainphoto']; ?&gt;)"&gt;
  &lt;div class="inner"&gt;
  &lt;header&gt;
  &lt;h1&gt;&lt;?php echo $row_hotel['hotel_name'] ?&gt;&lt;/h1&gt;
  &lt;h2&gt;&lt;?php echo $row_hotel['summary'] ?&gt;&lt;/h2&gt;
  &lt;/header&gt;
  &lt;a href="#main" class="more"&gt;Learn More&lt;/a&gt;
  &lt;/div&gt;
  
  &lt;!-- Main --&gt;
  &lt;div id="main"&gt;
  
  &lt;!-- Map Section --&gt;
  &lt;section class="wrapper style1" style="padding:0"&gt;
  &lt;div class="inner"&gt;
  &lt;!-- 2 Columns --&gt;
  &lt;div class="flex flex-2"&gt;
  &lt;div id="mapspace"&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;/div&gt;
  &lt;/section&gt;
  
  &lt;/div&gt;
  
  &lt;?php include('footer.php'); ?&gt;
  
          &lt;!-- Scripts --&gt;
              &lt;script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"&gt;&lt;/script&gt;
              &lt;script src="/js/jquery.scrolly.min.js"&gt;&lt;/script&gt;
              &lt;script src="/js/jquery.scrollex.min.js"&gt;&lt;/script&gt;
              &lt;script src="/js/skel.min.js"&gt;&lt;/script&gt;
              &lt;script src="/js/util.js"&gt;&lt;/script&gt;
              &lt;script src="/js/main.js"&gt;&lt;/script&gt;
              &lt;script src="/js/picker.js"&gt;&lt;/script&gt;
              &lt;script src="/js/lightgallery.min.js"&gt;&lt;/script&gt;
              &lt;script src="/js/lg-thumbnail.min.js"&gt;&lt;/script&gt;
              &lt;script src="/js/tooltip.js"&gt;&lt;/script&gt;
  
              &lt;link type="text/css" rel="stylesheet" href="/css/picker.css"&gt;
  
  &lt;script&gt;
  $(document).ready(function(){
      $("#maplink").click(function(){
       var txt = $("#mapspace").is(':visible') ? 'See location map' : 'Hide location map';
       $("#maplink").text(txt);
       $("#mapspace").slideToggle(2000, function() {
          $("#mapspace").load("/includes/map_hotel.php?hid=&lt;?php echo $row_hotel['hid'] ?&gt;");
      });
      $('html, body').animate({
          scrollTop: $("#maplink").offset().top
      }, 2000);
      });
  });
  &lt;/script&gt;
  &lt;/body&gt;
  &lt;/html&gt;
  </code></pre>
  
  <p>The map page is</p>
  
  <pre><code>&lt;!DOCTYPE HTML&gt;
  &lt;html&gt;
  &lt;head&gt;
  &lt;meta charset="utf-8"&gt;
  &lt;link rel="stylesheet" href="/css/main.css" /&gt;
  &lt;style&gt;
  html, body{height:100%;margin:0;padding:0}
  #map_canvas{height:100%}
  .info{font-family:Arial, Helvetica, sans-serif}
  .info h1{font-size:1.2em;font-weight:bold;color:#3498db;line-height:normal;margin-bottom:.1em}
  .thishotel{font-size:1.2em;font-weight:bold;color:#3498db;text-align:center}
  &lt;/style&gt;
  &lt;/head&gt;
  
  &lt;body&gt; 
  &lt;div id="map_canvas"&gt;&lt;/div&gt;
  
  &lt;script src="//maps.googleapis.com/maps/api/js?key=AIzaSyAVWhJbk79iVcXRDoaG75l7glsdS2hYRyo"&gt;&lt;/script&gt;
  &lt;script type="text/javascript" src="/js/downloadxml.js"&gt;&lt;/script&gt;
  &lt;script type="text/javascript" src="/js/infobox.js"&gt;&lt;/script&gt;
  &lt;script type="text/javascript"&gt; 
  google.maps.event.addDomListener(window,'load',initMap);
       // global "map" variable
        var map = null;
  
  // InfoBox
   var boxText = document.createElement("div");
          boxText.style.cssText = "border:1px solid #3498db;border-radius:5px;margin-top:8px;background:white;padding:5px;";
  
          var ibOptions = {
           content: boxText
          ,closeBoxURL: ""
          ,disableAutoPan: false
          ,enableEventPropagation: true
          ,maxWidth: 0
          ,pixelOffset: new google.maps.Size(15, -50)
          ,boxStyle: { 
           width: "240px"
           }
          };
  
  // global "infobox" variable
    var ib = new InfoBox(ibOptions);
  
  function createMarker(latlng, html) {
      var contentString = html;
  
      var marker = new google.maps.Marker({
          map: map,
          position: latlng,
          icon: "/images/hotel_grey_icon.gif",
          zIndex: 9998
          });
  
      google.maps.event.addListener(marker, 'mouseover', function() {
          boxText.innerHTML = contentString;
          ib.open(map, marker);
          });
        google.maps.event.addListener(map, 'click', function() {
          ib.close(map, marker);
          });
  }
  
  function initMap() {
        var lat = &lt;?php echo $row_hotel['latitude'] ?&gt;;
        var lng = &lt;?php echo $row_hotel['longitude'] ?&gt;;
        var zoom = 10;
    var thisLatlng = new google.maps.LatLng(lat, lng);
    var mapOptions = {
  center: thisLatlng,
  zoom: zoom,
  mapTypeId: google.maps.MapTypeId.ROADMAP,
     streetViewControl: true,
     scaleControl: true,
     zoomControl: true
     }
  
    map = new google.maps.Map(document.getElementById("map_canvas"), mapOptions);
  
    var hotelContentString = '&lt;div class="thishotel"&gt;&lt;?php echo $row_hotel['hotel_name'] ?&gt;&lt;/div&gt;';
  
    var hotelmarker = new google.maps.Marker({
        position: thisLatlng,
        map: map,
        icon: "/images/hotel_icon.gif",
        zIndex: 9999
    });
  
  // Infobox for this hotel
          var hibOptions = {
           content: boxText
          ,closeBoxURL: ""
          ,disableAutoPan: false
          ,enableEventPropagation: true
          ,maxWidth: 0
          ,pixelOffset: new google.maps.Size(-70, -75)
          ,boxStyle: { 
           width: "140px"
           }
          };
  
    var hib = new InfoBox(hibOptions);
  
        google.maps.event.addListener(hotelmarker, 'mouseover', function() {
          boxText.innerHTML = hotelContentString;
          hib.open(map, hotelmarker);
          });
        google.maps.event.addListener(map, 'click', function() {
          hib.close(map, hotelmarker);
          });
  
  var style_nopoi = [{"featureType": "poi", "stylers": [{"visibility": "off"}]}]; // Styles, removes points-of-interest. Lots of other possibilities.
  map.setOptions({styles: style_nopoi});  // Applies the style to the map
  
  var loadcnt = 0;
        google.maps.event.addListener(map, 'tilesloaded', function() {
          if (loadcnt==0) {
          map.setCenter(thisLatlng); // Seems to fix random centring problem on mobiles
          loadcnt=loadcnt+1;
          }
          });
  
        downloadUrl("/includes/php-to-xml.php?iso=&lt;?php echo $row_hotel['countryisocode'] ?&gt;", function(doc) {
          var xmlDoc = xmlParse(doc);
          var markers = xmlDoc.documentElement.getElementsByTagName("marker");
  
          for (var i = 0; i &lt; markers.length; i++) {
  
            var lat = parseFloat(markers[i].getAttribute("lat"));
            var lng = parseFloat(markers[i].getAttribute("lng"));
            var point = new google.maps.LatLng(lat,lng);
            var html=markers[i].getAttribute("html");
  
            createMarker(point, html);
          }
  
        });
      }
  &lt;/script&gt;
  &lt;/body&gt;
  &lt;/html&gt;
  </code></pre>
  
  <p>The automatic SO system has asked for an edit to explain why my question is not answered by other posts with similar titles. I've tried numerous similar posts and taken several solutions where they seemed relevant but none of them worked.</p>
  
  <p>SECOND EDIT. Further investigation seems to suggest that the problem is a conflict between Jquery and Google Maps, and not a problem with my script in the maps page Therefore to avoid this question getting any longer, I've opened a new question here: <a href="https://stackoverflow.com/questions/43394074/conflict-between-jquery-and-google-maps-api">https://stackoverflow.com/questions/43394074/conflict-between-jquery-and-google-maps-api</a></p>