# 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***

_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/)