Google maps JS API in sage 9

sage9

#1

Trying to get Google maps JS API working. Doing the same as in Sage 8, doesn’t work in Sage 9.

I have google maps JS API script enqueued succesfully, with its API key in app/setup.php.

wp_enqueue_script('google-maps', 'https://maps.googleapis.com/maps/api/js?key=' . env('GOOGLE_MAPS_API'), [], null, true);

Then, I have this simple code at routes/common.js:

$(function initMap() {
      let mapDiv = document.getElementById('map');
      let map = new google.maps.Map(mapDiv);
    })

But I get: error 'google' is not defined.

What am I missing?


#2

Try to add 'window.google': 'google' here:

And google: 'google' here:

Untested, but I believe this should work.

Since the Google Maps JS API is being loading as an external dependency — not a standard Node module — you need to tell Webpack that it is external and you can then use the providePlugin to provide it to all your scripts.


#3

I don’t think you should really need to do the ProvidePlugin step I have above. That would only be if you wanted to provide google to all the scripts. Instead, I would just add import google from 'google' where I need it.


#4

Ok, thank you very much for this explanation! :+1:t3::+1:t3::+1:t3:

I will try it in a while.


#5

Confirmed, it works. Imported into its specific route. Thanks again.


#6

Now how would this work if the script is enqueued on only one page?
For example I only use the places API on the checkout page of woocommerce, for autocompletion.

Thus i have:
if(is_checkout() || is_account_page()){ wp_enqueue_script('google-places', 'https://maps.googleapis.com/maps/api/js?v=3&libraries=places&key='.get_option( 'bull-api-keys-maps-key'), false, null ,false); }

However if include google: 'google' in the externals it goes looking for it on other pages as well. How would we go about this?


#7

Can be the answer in the function option for externals?

https://webpack.js.org/configuration/externals/#function

module.exports = {
  //...
  externals: [
    function(context, request, callback) {
      if (/^yourregex$/.test(request)){
        return callback(null, 'commonjs ' + request);
      }
      callback();
    }
  ]
};

I don’t know enough coding for solve it.


#8

Any ideas? I’m not that much of a webpack expert.


#9

What have you tried? Also, what are the errors you are running into?


#10

This below is my exact problem. Played around with a few things and search quite a lot however i have no clue on how to make this work even with the function.

This does seem like something that would happen commonly?


#11

You haven’t posted an error code, so it’s a little unclear what the problem is that you’re running into.

By default, Sage compiles all your javascript into a single file, and it does this using webpack. The issue Aitor was running into was that when webpack built that single JS file, it was unable to find the google library–because that library is enqueued by WordPress on the page when the site is visited, not included as part of build process. Adding google to externals tells webpack that when its building that single file, it doesn’t need to look for google because that library will be available when the script runs in the browser.

Sage also provides a system for routing JS scripts: there are examples that come with it. You can use this router to only import google on the routes where it’s actually needed.


#12

Sorry if I was unclear, i’ll try to explain it with errors.

The idea:
i’m using the Google Maps API on the WooCommerce checkout page to autocomplete the address fields.

Current Situation:
Currently I enqueue the Google Maps script in ‘setup.php’ on all pages. With the following code.
wp_enqueue_script('google-places', 'https://maps.googleapis.com/maps/api/js?v=3&libraries=places&key='.get_option( 'bull-api-keys-maps-key'), false, null ,false);

I also have a routed JS file on the checkout page. In which i do import google from 'google'; and the code that interacts with the api of course.

Then in webpack externals i have: google: 'google'

Wanted Outcome
Since i only use the Google Maps script on the checkout page, I only want to enqueue it there. Therefore I added in a check, to see if it is the checkout page ‘setup.php’
if(is_checkout()){ wp_enqueue_script('google-places', 'https://maps.googleapis.com/maps/api/js?v=3&libraries=places&key='.get_option( 'bull-api-keys-maps-key'), false, null ,false); }

Now this works fine on the checkout page, however on other pages i’m getting errors as the script is not included there. Uncaught Error: Cannot find module "google"

Now the question, how do we configure webpack correctly, so that it does not need 'google' to be available on every page?

Hopefully this is a bit more clear :wink:


#13

Having the exact same issue, so interested as well what sage people have to say :slight_smile:


#14

The simplest way to get this to work is to not use webpack externals and instead define google in your route this way:

const google = window.google;

#15

Well, I could have thought of that.
Thank you works perfectly!