DEV Community

Tareq Newaz Shahriar
Tareq Newaz Shahriar

Posted on • Updated on

How to add Google Map script in a Vue project - without plugins

[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:

// 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;
}
Enter fullscreen mode Exit fullscreen mode

Now in your callback, do whatever you wanted to do with Map. Here I will initialize Place Autocomplete:

<!-- 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>
Enter fullscreen mode Exit fullscreen mode

Finally, here's what we have:
Html input element with google map place autocomplete

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:

Top comments (4)

Collapse
 
prototypesean profile image
Dennis Kao

This is really helpful when I first trying to add google map to my current project,
but then I had to call map object from another component for street view, I can't pull it out :<

first I try to move

window.checkAndAttachMapScript = function (callback)

to root component, and have different callback function in different components, but got 'google is not define' error or

'You have included the Google Maps API multiple times on this page' error

can I bother you with a complete demo for a google map object using cross multiple components?

Collapse
 
tareqnewazshahriar profile image
Tareq Newaz Shahriar • Edited

Sorry, im late for 25 days ~facepalm~; haven't been checking dev.to for a while. Anyways.. did you solve it?

For now, I can point following things out-

first I try to move
window.checkAndAttachMapScript = function (callback)
to root component...

callback itself is a function, which is getting passed to another function. So not sure whether you made a typo here or you know exactly what you are doing!

but got 'google is not define' error

This is the reason I wrote this post. If you write new google.maps.StreetViewPanorama(...), you will get "google is not defined" error. You have to write: new window.google.maps.StreetViewPanorama(...).

'You have included the Google Maps API multiple times on this page' error

Probably every time you are calling checkAndAttachGoogleMap method, you are adding another <script> tag. So you need to review your code.

Collapse
 
matthew profile image
Matthew Hodge

Dude this helped me so much thank you!

Collapse
 
tareqnewazshahriar profile image
Info Comment hidden by post author - thread only accessible via permalink
Tareq Newaz Shahriar

Hahaha... maybe you're talking about my first para.

Some comments have been hidden by the post's author - find out more