# Google Map With NextJs / ReactJs (react-google-map) <div> <img src="https://i.imgur.com/1EIOPQm.png" style="width: 50px" /> <img src="https://i.imgur.com/AVOw4tg.png" style="width: 50px" /> <img src="https://i.imgur.com/9oDcX1u.png" style="width: 50px" /> </div> #### Author: Yim Sotharoth <div> <b>Organized By Metaphorlism</b> <img src="https://i.imgur.com/a8rbSuD.jpg" style="width: 30px"/> </div> ### Using NPM (Node Package Manager) :::warning :bulb: **Before Getting Started** You firstly need to create a new next/react project if you don't have one. _To create react project_ ```bash $ npx create-react-app app_name ``` _To create next project_ ```bash $ npx create-next-app app_name ``` _After you created your project you will need to install the google map library_ ```bash $ npm install @react-google-maps/api ``` [Learn more about the library here →](https://www.npmjs.com/package/@react-google-maps/api) ::: :::info Before getting your hands dirty, you firstly need to create a folder calls Components (Or comps) then create a component name Map in Map.js ::: ### Implement Google Map in Components/Map.js ```javascript import { GoogleMap, useLoadScript } from "@react-google-maps/api"; const Map = () => { // laod script for google map const { isLoaded } = useLoadScript({ googleMapsApiKey: process.env.NEXT_PUBLIC_GOOGLE_MAPS_API_KEY, }); if (!isLoaded) return <div>Loading....</div>; // static lat and lng const center = { lat: 'YOUR-LATITUDE', lng: 'YOUR-LONGITUDE' }; return ( <div style={{ display: "flex", flexDirection: "column", justifyContent: "center", alignItems: "center", gap: "20px", }} > {/* map component */} <GoogleMap zoom={currentLocation || selectedPlace ? 18 : 12} center={currentLocation || searchLngLat || center} mapContainerClassName="map" mapContainerStyle={{ width: "80%", height: "600px", margin: "auto" }} > </GoogleMap> </div> ); }; export default Map; ``` :::info In this example we only implement the map without any actions `const { isLoaded } = useLoadScript({ googleMapsApiKey: process.env.NEXT_PUBLIC_GOOGLE_MAPS_API_KEY, });` **Create a .env file to store the process.env.NEXT_PUBLIC_GOOGLE_MAPS_API_KEY** `zoom={currentLocation || selectedPlace ? 18 : 12}` **Make sure you change the zoom value to your prefer otherwise you will get error** ::: ### Implement Search and AutoComplete/Search to Map in Components/Map.js :::info Create new states ::: ```javascript const [selectedPlace, setSelectedPlace] = useState(null); const [searchLngLat, setSearchLngLat] = useState(null); const autocompleteRef = useRef(null); const [address, setAddress] = useState(""); ``` :::info Below is the function to handle autocomplete/search action ::: ```javascript // handle place change on search const handlePlaceChanged = () => { const place = autocompleteRef.current.getPlace(); setSelectedPlace(place); setSearchLngLat({ lat: place.geometry.location.lat(), lng: place.geometry.location.lng(), }); setCurrentLocation(null); }; ``` :::info Add this to get the input field ::: ```javascript {/* search component */} <Autocomplete onLoad={(autocomplete) => { console.log("Autocomplete loaded:", autocomplete); autocompleteRef.current = autocomplete; }} onPlaceChanged={handlePlaceChanged} options={{ fields: ["address_components", "geometry", "name"] }} > <input type="text" placeholder="Search for a location" /> </Autocomplete> ``` :+1: Here is the complete code after implementing autocomplete ```javascript import { useState, useRef } from "react"; import { GoogleMap, useLoadScript, Marker, Autocomplete, } from "@react-google-maps/api"; const Map = () => { const [selectedPlace, setSelectedPlace] = useState(null); const [searchLngLat, setSearchLngLat] = useState(null); const autocompleteRef = useRef(null); const [address, setAddress] = useState(""); // laod script for google map const { isLoaded } = useLoadScript({ googleMapsApiKey: process.env.NEXT_PUBLIC_GOOGLE_MAPS_API_KEY, libraries: ["places"], }); if (!isLoaded) return <div>Loading....</div>; // static lat and lng const center = { lat: 'YOUR-LATITUDE', lng: 'YOUR-LONGITUDE' }; // handle place change on search const handlePlaceChanged = () => { const place = autocompleteRef.current.getPlace(); setSelectedPlace(place); setSearchLngLat({ lat: place.geometry.location.lat(), lng: place.geometry.location.lng(), }); setCurrentLocation(null); }; return ( <div style={{ display: "flex", flexDirection: "column", justifyContent: "center", alignItems: "center", gap: "20px", }} > {/* search component */} <Autocomplete onLoad={(autocomplete) => { console.log("Autocomplete loaded:", autocomplete); autocompleteRef.current = autocomplete; }} onPlaceChanged={handlePlaceChanged} options={{ fields: ["address_components", "geometry", "name"] }} > <input type="text" placeholder="Search for a location" /> </Autocomplete> {/* map component */} <GoogleMap zoom={currentLocation || selectedPlace ? 18 : 12} center={currentLocation || searchLngLat || center} mapContainerClassName="map" mapContainerStyle={{ width: "80%", height: "600px", margin: "auto" }} onLoad={onMapLoad} > {selectedPlace && <Marker position={searchLngLat} />} </GoogleMap> </div> ); }; export default Map; ``` ### Implement get current location to Map in Components/Map.js :::info Create new states ::: ```javascript const [currentLocation, setCurrentLocation] = useState(null); ``` :::info Below is the function to handle get current location action ::: ```javascript // get current location const handleGetLocationClick = () => { if (navigator.geolocation) { navigator.geolocation.getCurrentPosition( (position) => { const { latitude, longitude } = position.coords; setSelectedPlace(null); setSearchLngLat(null); setCurrentLocation({ lat: latitude, lng: longitude }); }, (error) => { console.log(error); } ); } else { console.log("Geolocation is not supported by this browser."); } }; // on map load const onMapLoad = (map) => { const controlDiv = document.createElement("div"); const controlUI = document.createElement("div"); controlUI.innerHTML = "Get Location"; controlUI.style.backgroundColor = "white"; controlUI.style.color = "black"; controlUI.style.border = "2px solid #ccc"; controlUI.style.borderRadius = "3px"; controlUI.style.boxShadow = "0 2px 6px rgba(0,0,0,.3)"; controlUI.style.cursor = "pointer"; controlUI.style.marginBottom = "22px"; controlUI.style.textAlign = "center"; controlUI.style.width = "100%"; controlUI.style.padding = "8px 0"; controlUI.addEventListener("click", handleGetLocationClick); controlDiv.appendChild(controlUI); // const centerControl = new window.google.maps.ControlPosition( // window.google.maps.ControlPosition.TOP_CENTER, // 0, // 10 // ); map.controls[window.google.maps.ControlPosition.TOP_CENTER].push( controlDiv ); }; ``` :::info Add onLoad into <GoogleMap></GoogleMap> `onLoad={onMapLoad}` ::: :+1: Here is the complete code after implementing get current location ```javascript import { useState, useRef } from "react"; import { GoogleMap, useLoadScript, Marker, Autocomplete, } from "@react-google-maps/api"; const Map = () => { const [selectedPlace, setSelectedPlace] = useState(null); const [searchLngLat, setSearchLngLat] = useState(null); const [currentLocation, setCurrentLocation] = useState(null); const autocompleteRef = useRef(null); const [address, setAddress] = useState(""); // laod script for google map const { isLoaded } = useLoadScript({ googleMapsApiKey: process.env.NEXT_PUBLIC_GOOGLE_MAPS_API_KEY, libraries: ["places"], }); if (!isLoaded) return <div>Loading....</div>; // static lat and lng const center = { lat: 'YOUR-LATITUDE', lng: 'YOUR-LONGITUDE' }; // handle place change on search const handlePlaceChanged = () => { const place = autocompleteRef.current.getPlace(); setSelectedPlace(place); setSearchLngLat({ lat: place.geometry.location.lat(), lng: place.geometry.location.lng(), }); setCurrentLocation(null); }; // get current location const handleGetLocationClick = () => { if (navigator.geolocation) { navigator.geolocation.getCurrentPosition( (position) => { const { latitude, longitude } = position.coords; setSelectedPlace(null); setSearchLngLat(null); setCurrentLocation({ lat: latitude, lng: longitude }); }, (error) => { console.log(error); } ); } else { console.log("Geolocation is not supported by this browser."); } }; // on map load const onMapLoad = (map) => { const controlDiv = document.createElement("div"); const controlUI = document.createElement("div"); controlUI.innerHTML = "Get Location"; controlUI.style.backgroundColor = "white"; controlUI.style.color = "black"; controlUI.style.border = "2px solid #ccc"; controlUI.style.borderRadius = "3px"; controlUI.style.boxShadow = "0 2px 6px rgba(0,0,0,.3)"; controlUI.style.cursor = "pointer"; controlUI.style.marginBottom = "22px"; controlUI.style.textAlign = "center"; controlUI.style.width = "100%"; controlUI.style.padding = "8px 0"; controlUI.addEventListener("click", handleGetLocationClick); controlDiv.appendChild(controlUI); // const centerControl = new window.google.maps.ControlPosition( // window.google.maps.ControlPosition.TOP_CENTER, // 0, // 10 // ); map.controls[window.google.maps.ControlPosition.TOP_CENTER].push( controlDiv ); }; return ( <div style={{ display: "flex", flexDirection: "column", justifyContent: "center", alignItems: "center", gap: "20px", }} > {/* search component */} <Autocomplete onLoad={(autocomplete) => { console.log("Autocomplete loaded:", autocomplete); autocompleteRef.current = autocomplete; }} onPlaceChanged={handlePlaceChanged} options={{ fields: ["address_components", "geometry", "name"] }} > <input type="text" placeholder="Search for a location" /> </Autocomplete> {/* map component */} <GoogleMap zoom={currentLocation || selectedPlace ? 18 : 12} center={currentLocation || searchLngLat || center} mapContainerClassName="map" mapContainerStyle={{ width: "80%", height: "600px", margin: "auto" }} onLoad={onMapLoad} > {selectedPlace && <Marker position={searchLngLat} />} {currentLocation && <Marker position={currentLocation} />} </GoogleMap> </div> ); }; export default Map; ``` :::success After implement these code you will be able to use Google Map with autocomplete and get current location ***Note that I set my latitude and longitude at the center of London*** ![](https://i.imgur.com/cfL7BrY.jpg) _But if you still find any problem you can check this repository out_ [This Project's GitHub Repository](https://github.com/JBeanny/google-map-next) ::: ### Contact Us - :mailbox: yimsotharoth999@gmail.com - [GitHub](https://github.com/JBeanny) - [Facebook Page](https://www.facebook.com/Metaphorlism) - [Instagram: Metaphorlism](https://www.instagram.com/metaphorlism/)