Concept Welder

"Where new ideas are forged and brought to life"

Google Map with Nextjs

Integrating Google Maps into a Next.js project can enhance your application's interactivity and user experience. In this article, we'll explore how to seamlessly incorporate Google Maps, add markers, and customize its features using the @vis.gl/react-google-maps version 1.1.0 package

The Google Maps API key and Google Map ID used for advanced map features can be obtained from the Google Maps Platform.

Complete source

Step 1 with Basic marker

One of the fundamental tasks when working with maps is displaying a marker. In this article, we'll start with that basic step and explore how to add more and more features to Google Maps.

<APIProvider apiKey={googleMapsApiKey}>
<Map
    defaultCenter={mapCenter}
    defaultZoom={5}
    mapId={googleMapId}
>
    <AdvancedMarker
    position=
    >
    </AdvancedMarker>
</Map>
</APIProvider>
                                
See the source

Customizations & Multiple markers

Here are some customizations to the pin, And adding more markers from an array.

places.map((place: Place, key: number) => (
<AdvancedMarker
    position=
    key={key}
>
    <Pin background={'#FF00FF'} borderColor={'#FF00FF'} glyphColor={'#FFFFFF'}></Pin>
</AdvancedMarker>
))     
                            
See the source

Info window

Let's first show a small information window, and in the next step, improve it to open only when clicking on the marker.

places.map((place: Place, key: number) => (
<div>
    <AdvancedMarker
    position=
    key={key}
    >
    <Pin background={'#FF00FF'} borderColor={'#FF00FF'} glyphColor={'#FFFFFF'}></Pin>
    </AdvancedMarker>
    <InfoWindow
    position=
    key={key}
    >
    <div>
        <h4>{place.name}</h4>
        <p>{place.intro}</p>
    </div>
    </InfoWindow>
</div>
))
                            

See the source

Next step, Marker click behavior

Marker Clustering

Clustering is a beautiful feature available in Google Maps; let's see how we can implement it. By using @googlemaps/markerclusterer package.

const clusterer = useRef<MarkerClusterer | null>(null);

useEffect(() => {
    if (!map) return;
    if (!clusterer.current) {
        clusterer.current = new MarkerClusterer({ map });
    }
}, [map])

useEffect(() => {
    clusterer.current?.clearMarkers();
    clusterer.current?.addMarkers(Object.values(markers))
}, [markers])

const setMarkerRef = (marker: Marker | null, key: number) => {
    if (marker && markers[key]) return;
    if (!marker && !markers[key]) return;

    setMarkers((prev) => {
        if (marker) {
            return { ...prev, [key]: marker };
        } else {
            const newMarker = { ...prev };
            delete newMarker[key];
            return newMarker;
        }
    });
}
                            

See the source

Beauty of clustering

See the beauty of clustering.

Address search

Let's integrate Google address search into the map using the @react-google-maps/api npm package.

const AutoCompleteOptions = {
componentRestrictions: { country: 'LK' },
};

const onLoad = (autocomplete: google.maps.places.Autocomplete) => {
    setSearchResult(autocomplete);
}
                    
<Autocomplete
onLoad={onLoad}
onPlaceChanged={onPlaceChangedEvent}
options={AutoCompleteOptions}
>
<input
className="form-control"
type="text"
placeholder="Enter postcode, suburb or locator name"
></input>
</Autocomplete>
                            

See the source

Locate to the address

When the user searches for an address, let's display that location on the map.

const zoomToLocation = (location: LatLngLiteral) => {
if (map) {
    map.setCenter({
        lat: location.lat,
        lng: location.lng,
    })
    map.setZoom(10);
}
}

const onPlaceChangedEvent = () => {
if (searchResult) {
    const place = searchResult.getPlace();
    if (place?.geometry?.location) {
        const placeLat = place.geometry?.location?.lat()
        const placeLng = place.geometry?.location?.lng()
        zoomToLocation({
            lat: placeLat,
            lng: placeLng,
        });
    }
}
}
                            
See the source

Position of a user

Use the HTML Geolocation API to get the user's geographical position and display it on the map

if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition((position) => {
    zoomToLocation({
        lat: position.coords.latitude,
        lng: position.coords.longitude,
    });
})
}
                            
See the source

Mark an area

Here's how to mark an area on Google Maps.

new google.maps.Circle({
strokeColor: "#FF0000",
strokeWeight: 2,
fillColor: "#FF0000",
map,
center: latlng,
radius: 3000,
})
                            
See the source