Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add Google Map to GatsbyJS with Maps JavaScript API

I'm trying to add a map to my Gatsby project using the Google Maps JavaScript API.

I'm customizing the Gatsby html.js via a copy of the default one:

cp .cache/default-html.js src/html.js

Then, as per the Google Maps Hello World example, and after some Googling, I've figured out I needed to use dangerouslySetInnerHTML and add the following before my closing </body> tag in that new html.js:

<script dangerouslySetInnerHTML={{
    __html: `
      var map;
      function initMap() {
        map = new google.maps.Map(document.getElementById('map'), {
          center: {lat: -34.397, lng: 150.644},
          zoom: 8
        });
      }
    `
</script>
<script src="https://maps.googleapis.com/maps/api/js?key=MY_KEY&callback=initMap"
async defer></script>

(obviously, replacing MY_KEY with my actual API key)

I then created an empty <div id="map"></div> in my React component.

This works...sorta. If I navigate away, and return to the page with the map, it will disappear. I can only see the map if I reload the page that it is on.

Any ideas?

like image 804
skube Avatar asked Mar 07 '23 02:03

skube


2 Answers

This is the implementation I used to get Google Maps into my Gatsby build:

import React from 'react';
import GoogleMapReact from 'google-map-react';

const isClient = typeof window !== 'undefined';

export const GoogleMap = (props) => {
  const {
    address,
    googleMapsApiKey
  } = props;
  const lat = parseFloat(address.lat);
  const lng = parseFloat(address.lng);
  return (
    <section className="google-map">
      <div className="map">
        { isClient && (
          <GoogleMapReact
            bootstrapURLKeys={{ key: googleMapsApiKey }}
            defaultCenter={[lat, lng]}
            defaultZoom={14}
          >
            <div
              className="marker"
              lat={lat}
              lng={lng}
            />
          </GoogleMapReact>
        )}
      </div>
    </section>
  );
}

Note the isClient conditional rendering is important so that google-map-react doesn't break your Gatsby build!

like image 115
Allan of Sydney Avatar answered Mar 17 '23 00:03

Allan of Sydney


I'm not sure if this will help you or not, but here's what I did:

  1. cp .cache/default-html.js src/html.js
  2. Edit src/html.js and put <script src="https://maps.googleapis.com/maps/api/js?key=MY_KEY&callback=initMap" async defer></script> at the bottom of the body tag.
  3. Put the map initialization in componentDidMount() of the component that renders #map.

Step 3 could look like this:

import React, { Component } from 'react'

export default class Map extends Component {
  initMap = () => {
    new window.google.maps.Map(document.getElementById('map'), {
      center: { lat: 40, lng: 10 },
      zoom: 5,
    })
  }

  componentDidMount() {
    this.initMap()
  }

  render() {
    return <div id="map" />
  }
}
like image 40
abrad45 Avatar answered Mar 17 '23 01:03

abrad45