Kamran
Kamran

Reputation: 829

You have included the Google Maps JavaScript API multiple times on this page

How can I avoid “You have included the Google Maps JavaScript API multiple times on this page. This may cause unexpected errors.” if I am using google-map-react to display the map and react-places-autocomplete in another component to get the address and coordinates?

// LocationMapPage component that displays the map box and pass the props to it
class LocationMapPage extends Component {

  render() {
    let {latLng,name,address} = this.props.location;
    return (
        <MapBox lat={latLng.lat} lng={latLng.lng} name={name} address={address}/>
    )
  }
  
}

//MapBox component
import React from "react";
import GoogleMapReact from 'google-map-react';
import apiKey from "../../configureMap";


const Marker = () => <i className="fa fa-map-marker fa-2x text-danger" />

const MapBox = ({lat,lng, name, address}) => {
    const center = [lat,lng];
    const zoom = 14;
    return (  
        <div style={{ height: '300px', width: '100%' }}>
            <GoogleMapReact
            bootstrapURLKeys={{ key: apiKey }}
            defaultCenter={center}
            defaultZoom={zoom}
            >
            <Marker
                lat={lat}
                lng={lng}
                text={`${name}, ${address}`}
            />
            </GoogleMapReact>
      </div>
    );
}
 
export default MapBox; 

Map is blank:

enter image description here The Error in the console:You have included the Google Maps JavaScript API multiple times on this page. This may cause unexpected errors.

How to solve?

I am using google-map-react, react-places-autocomplete in the project.

Upvotes: 9

Views: 18743

Answers (4)

Jasperan
Jasperan

Reputation: 3895

You can fix this error by checking if the Google Maps api script is already added to the document head. This code creates a script element, checks if there already exists a google maps script in index.html, and if not, appends it to the document head.

useEffect(() => {
  const scriptSrc = `https://maps.googleapis.com/maps/api/js?key=${apiKey}&libraries=places&callback=initMap`;
  // Only load the script if it is not already loaded
  const alreadyLoaded = document.querySelectorAll(`script[src="${scriptSrc}"]`).length > 0;
  if (!alreadyLoaded) {
    const googleMapScript = document.createElement("script");
    googleMapScript.src = scriptSrc;
    document.head.appendChild(googleMapScript);
  }

  window.initMap = initMap;
}, []);

Upvotes: 0

Kamran
Kamran

Reputation: 829

As a temporary solution to my specific use case where I use the google map API's in two different components I have just added the script in the index.html:

<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&libraries=places"></script> 

I did it in order to avoid that particular error as per of the documentation on the react-places-autocomplete GitHub page.

Upvotes: 7

sdo
sdo

Reputation: 795

You could set a global variable and load the Google JavaScript only if the global variable is not set:

<script type="text/javascript">
    if(document.isLoadingGoogleMapsApi===undefined) {
        document.isLoadingGoogleMapsApi=true;
        var script = document.createElement('script');
        script.src='https://maps.googleapis.com/maps/api/js?key=[your-key]&callback=[yourInitMethodName]&v=weekly';
        script.type='text/javascript';
        script.defer=true;
        document.getElementsByTagName('head')[0].appendChild(script);
    }else{
        [yourInitMethodName]();
    }
</script>

In my case there is an arbitrary number of maps in a web application (starting at 0) and the user can add additional maps at runtime. Most of the users do not use any map so loading it by default would cost unnecessarily loading time.

Upvotes: 2

Stewko
Stewko

Reputation: 1

Unfortunately the link in the head of the index.html caused the same error. I found another workaround. Not the best solution, but works for now:

import React, { useEffect, useState } from 'react';
import GoogleMapReact from 'google-map-react';

export default () => {

    const [mapActive, setMapActive] = useState(false);

    useEffect(() => {
        const t = setTimeout(() => {
            setMapActive(true)
        }, 100);

        return () => {
            window.clearTimeout(t);
        };
    }, [])

    return (
            <>
                { mapActive && <GoogleMapReact
                    bootstrapURLKeys={ {
                        key: ...,
                        language: ...
                    } }
                    defaultCenter={ ... }
                    defaultZoom={ ... }
                >

                </GoogleMapReact> }
            </>
    );
};

Upvotes: 0

Related Questions