How to add Google Map script in a Vue project - without plugins
Tags: vue2, googlemap
Published: 2020-04-25 19:52:02

[v2.1, Code updated June 2021]

Why on earth everyone is using plugins just to add Map script and to call its APIs/methods! VueJS is Javascript, Map APIs available in Javascript, yet... can't you just use it?!

**The only important thing is** - for Vue CLI project, the time when you use the `google.maps` object, transpiler will show an error; you have to add the *window* scope explicitly like `new window.google.maps...()`.

Let's dive into the detail. We will use a function to attach the Map script programmatically (you can add the Map `<script>` tag directly in html, but that have caveat; check footnote). If you need Map APIs on multiple views then make this function/method global by placing it in *`vue.mixin`* or *`index.html`* etc. Otherwise you can use it in your desired component making it a method. Here I'm going to use it as a global function:
```js
// Add google map script if not exist; if already exist, return true
window.checkAndAttachMapScript = function (callback) {
   let scriptId = "map-api-script";
   let mapAlreadyAttached = !!document.getElementById(scriptId);

   if (mapAlreadyAttached) {
      if (window.google) // Script attached but may not finished loading; so check for 'google' object.
         callback();
   }
   else {
      window.mapApiInitialized = callback;

      let script = document.createElement('script');
      script.id = scriptId;
      script.src = 'https://maps.googleapis.com/maps/api/js?key=_YOUR_KEY_HERE_&libraries=places,geometry&callback=mapApiInitialized';
      document.body.appendChild(script);
   }

   return mapAlreadyAttached;
}
```

Now in your `callback`, do whatever you wanted to do with Map. Here I will initialize Place Autocomplete:
```vuejs
<!-- Vue single-file component -->
<template>
   <div>
      <input
         type="text"
         ref="search"
         v-model="location"
      />
   </div>
</template>

<script>
export default {
   data: () => ({
      location: null
   }),
   mounted() {
      window.checkAndAttachMapScript(this.initLocationSearch);
   },
   methods: {
      initLocationSearch() {
         let autocomplete = new window.google.maps.places.Autocomplete(this.$refs.search);
         autocomplete.addListener("place_changed", function() {
            let place = autocomplete.getPlace();
            if (place && place.address_components) {
               console.log(place.address_components);
            }
         });
      }
   }
};
</script>
```

Finally, here's what we have:
![Html input element with google map place autocomplete](https://dev-to-uploads.s3.amazonaws.com/i/fdquppxks0n0uhkio263.png)

**The End**

------------------------

##### Footnote
Attaching script programmatically will have more control. If a visitor directly landed on a page of your application where Map API is not need, then the script will not be loaded. If you add it directly in *index.html*, it will be loaded whether used or not. Eventually unnecessarily consumes bandwidth and CPU+battery on mobile devices.

##### Reference:
* List of libraries for `libraries=` querystring:
https://developers.google.com/maps/documentation/javascript/libraries