Build Google Maps Search Component in React (Part One)
Published: 2022-09-07 19:02:09

This is the first of a two part series on how to build a google maps search component.


First you are going to need the google maps package for react:


##Install Dependencies
``` ruby
#add these files to your package.json file within the react client folder.
  "@googlemaps/react-wrapper": "^1.1.35",
  "@react-google-maps/api": "^2.12.1",
   "google-maps-react": "^2.0.6",
```

##Create Google Map API Key

Next, you are going to need a few different google maps API keys throughout this process. These are codes that google provides you when you create a paid google account that allow you to access features from the google maps API. Do not worry, you won't necessarily be charged unless you approach production levels. Google only charges you fractions of dollar for every API request and provides its users with $200 monthly credit. So as long as your site doesn't make too many requests, you won't be charged. In your browser, navigate to `https://developers.google.com/` and follow the prompts to set up a paid account.

Then, you can follow the prompts on this page [https://developers.google.com/maps/documentation/javascript/get-api-key](https://developers.google.com/maps/documentation/javascript/get-api-key) to get your API key. You will need to create a "project" and select which API key you would like to use. In this case, we are going to start with the the Google Maps JavaScript API. 

Navigate to [The Google Maps API Homepage](https://console.cloud.google.com/projectselector2/google/maps-apis) and click on Credentials. At the top of the screen select "create credentials". No need to copy this key yet as we are going to add some restriction before we embed the key in our code.

Next, click on the new API key to see the options for that key. Unlike some of the other API keys we will use in phase two of this project, there is really no way to use the Google Maps JavaScript API in react without the key being made public to anyone viewing the page. That's ok. Google gives you special restriction options you can implement to protect your key from being overused in the wrong hands. Later on, we are going to look at how to conceal a different API key that google provides, but for now, let's adjust the configuration of our API restrictions for this key.

First off, under `APPLICATION RESTRICTIONS` select `
HTTP referrers (web sites)` and specify the domain where you will be making your requests. If you are in development mode, this will likely be "http://localhost:3000/" or some similar domain. However, when you deploy your app you will need to add the new domain for the API requests to still work. If you will be calling the api from multiple client-side routes within your project, set the domain here to the domain name followed by an asterisk symbol, such as "http://localhost:3000/*".

Next up, you are going to want to select "Restrict Key" from "API Restrictions" and add only the Maps JavaScript API from the drop down list. This prevents your key from being used for other API services that you may not have put quotas on.

Finally, we are going to accept these restrictions, and in the menu bar on the left where you earlier navigated to 'Credentials', navigate now instead to "Quotas". Select 'Maps JavaScript API' from the drop down menu at the top and place a restriction on every type of call possible from that API. Personally, I set my limit to 500 calls per day and had no trouble staying below this during development. As long as your quotas are below the free credit Google provides, you should be safe. Please keep in mind that I am no expert in API security. I am merely sharing the steps I took. Google has extensive documentation about other security features you may implement that I won't cover in this blog.

##Build First Map Component in React
Now that we have the key set up, let's build our first map component. Add a file called 'MapContainer.js' to your components' directory and add the following code:

``` javascript
import React from 'react';

//import the needed components from the Google Maps API
import { GoogleMap, LoadScript} from '@react-google-maps/api';

//Create the React Component Function
function MapContainer(){

//These are default map styles so your map is visible
const mapStyles = {        
    height: "50vh",
    width: "100%"}; 

//default latitude and longitude where the map will display
const defaultCenter = {
    lat: 35,
    lng: -105
  }
  

  return (
    
//the LoadScript hook is needed here to access the Google Maps Javascript API. This basically tells react to build a script component into the final html on the page, which is how google verifies your API key.
     <LoadScript
            googleMapsApiKey='Your_API_KEY_HERE'>
        <GoogleMap
          mapContainerStyle={mapStyles}
          zoom={13}
          center={defaultCenter}
        >
         </GoogleMap>
        
     </LoadScript>
  )
}
export default MapContainer;

```

The important thing here is that you replace the text 'Your_API_KEY_HERE' with your actual API key you obtained in the previous segment.

Then, in the App.js component, we need to include our new MapContainer.js component like this:

``` javascript
import logo from './logo.svg';
import './App.css';
import MapContainer from './components/MapContainer';

function App() {
  return (
    <div className="App">
      <MapContainer />
    </div>
  );
}

export default App;

```

This way we should be able to see the map in the browser.

##Don't push your key to GITHUB.

In your browser window, right click and select 'view source'. Within the resulting HTML, go ahead and click on `src="/static/js/bundle.js"`. Then hit control-f and search for "googleMapsApiKey". Right next to that phrase in this html page, in plain, readable string format, will be your API key. As you can see, anyone viewing this site will be able to snatch your secret API key. In the case of the Google Maps Javascript API this isn't actually a problem, since we have put into effect controls to restrict the usage of this key on the google site. Just as anyone can obtain your key from the html, the same would be true if we pushed these files to GITHUB as is. Anyone who cloned your project would have access to your API key. This is not a good thing. While we have controls in place to prevent large scale abuse, GITHUB is notorious for being plagued by roving web scrapers on the hunt for carelessly attached API KEYS. Pushing your API in the text of your code is like leaving a rib-eye steak on your porch in grizzly bear country...Someone is bound to take the bait. 

Because of this, we are going to walk through the process of hiding our Google Maps javascript API key so that it won't be pushed onto GITHUB. It will still be copiable from your deployed application, but that is not quite as dangerous as having it on GITHUB. Sadly, we have no choice in this case because Google Maps requires the script to be called from the html in order to view the map. Later on, we will see how to conceal an API key so that it is not accessible in on-site HTML either, but for our Google Map JavaScript API key we will only hide that key from being pushed to GITHUB.

Start by making a file in your client directory called ".env". These .env files let you customize your individual working environment variables. In order to make use of this you will need at least `react-scripts@0.2.3` or higher in your react app's dependencies. This should be automatically handled when you use `npx create-react-app`.

In your .env file, you must start the name of the API environment variable you wish to use with the words 'REACT-APP'. For example, you could add the following code to your .env file:`REACT_APP_API_KEY= AIzaSyBWgz_QMa3Awqe1TpfueOf11xIBa7Eo`

Then, in order to call your environment variable in your map, add the following code to your MapContainer.jsx file:

```javascript 
const API_KEY = process.env.REACT_APP_API_KEY;
```

This is telling javascript to retrieve environment variables from the local .env file. Your entire component should look like this:

```javascript
import React from 'react';

//import the needed components from the Google Maps API
import { GoogleMap, LoadScript} from '@react-google-maps/api';

//refer the map API Key from the env file
const API_KEY = process.env.REACT_APP_API_KEY;

//Create the React Component Function
function MapContainer(){

//These are default map styles so your map is visible
const mapStyles = {        
    height: "50vh",
    width: "100%"}; 

//default latitude and longitude where the map will display
const defaultCenter = {
    lat: 35,
    lng: -105
  }
  

  return (
    
//the LoadScript hook is needed here to access google maps. This basically tells react to build a script component into the final html on the page, which is how google verifies your API key.
     <LoadScript
            googleMapsApiKey= {API_KEY} >
        <GoogleMap
          mapContainerStyle={mapStyles}
          zoom={13}
          center={defaultCenter}
        >
         </GoogleMap>
        
     </LoadScript>
  )
}
export default MapContainer;
```

Upon completion of this step you may need to restart your react server to see the map updated. The final step in this segment is to include the .env file in your .gitignore file within your client folder. 

In your client directory's .gitignore file, simply add: `.env` to a new line and voila, your API will no longer be pushed up to GitHub.

Here is one potential catch, however. Say you are deploying your code. For this example, let's assume you are using the third party site Heroku. In this case, since you are not pushing your .env file to heroku, you will need to specify your environment variable in heroku. In the command line, cd into your rails app directory and run `heroku config:set REACT_APP_API_KEY= AIzaSyBWgz_Qasdfsdfdse1TpfueOf11xIBa7Eo`. This essentially accomplishes the same thing as the .env file, but you are stating the value of that environment variable directly in Heroku.

Next up, continue on to Part Two of the Blog Post to find out how to build the search feature: [Here](https://dev.to/jpstupfel/build-google-maps-search-component-in-react-part-two-57l8)