wellyshen / use-places-autocomplete

😎 📍 React hook for Google Maps Places Autocomplete.
https://use-places-autocomplete.netlify.app
MIT License
1.26k stars 65 forks source link

Next.js Integration #1036

Open paularah opened 2 years ago

paularah commented 2 years ago

I would appreciate a definitive guide on using this with next.js. The Next.js script tag with a beforeInteractive strategy gives the error use-places-autocomplete: Google Maps Places API library must be loaded. The native script tag only works with asynchronous loading since external synchronous scripts are forbidden in Next.js. asynchronously loading the script occasionally freezes the input field.

clearly-outsane commented 2 years ago

I have this problem too

DopamineDriven commented 2 years ago

Per the recent Nextjs shift in best practices for loading beforeInteractive scripts, you can instantiate the library as pictured and it works perfectly. I’m using next@latest, edge middleware, etc etc; works with next@12.x.x AA66211F-B6D6-49DC-85FB-90708DD14C6A

if anyone has tips for using the returned latlng values with Algolia InstantSearch Hooks it’d be much appreciated. I currently have it all working in isolation; but when using both Google places and algolia in the same form the fetching strategies clash I think (fiddling with Promise.all([]) but might say fuck it and use global context, keep the worlds separate).

That said, it would be dope to see an algolia-instantsearch-hooks use places autocomplete integration 4ED8D13C-9C3E-4A1F-88C6-5611F3A8B35A

scottschindler commented 2 years ago

@DopamineDriven Thanks.

Is that code in "pages/_document.js"? I have similar code in document and it's not working for me.

import { Html, Head, Main, NextScript } from "next/document";
import Script from "next/script";

export default function Document() {
  return (
    <Html>
      <Head />
      <body>
        <Main />
        <NextScript />
        <Script
          id="googlemaps"
          type="text/javascript"
          strategy="beforeInteractive"
          src="https://maps.googleapis.com/maps/api/js?key=KEY-4Q&libraries=places"
        />
      </body>
    </Html>
  );
}
dgaitsgo commented 2 years ago

Without making the script available everywhere, putting it in _document, only this helped resolve the issue: https://github.com/wellyshen/use-places-autocomplete/discussions/883#discussioncomment-2791354

Edit: the above only partially worked, since it would load once and no longer work on refresh. Workaround: https://github.com/vercel/next.js/discussions/17919#discussioncomment-3149719

avaneeshtripathi commented 2 years ago

Reason: This issue occurs when usePlacesAutocomplete is initialized before the Google Maps script is loaded.

Solution: This can be accomplished with any of the strategies.

  1. beforeInteractive should anyways work as the google map script is loaded initially. But if it doesn't, same solution can be applied for that as well.
  2. if we have issues with afterInteractive or lazyOnLoad. we can do the following:

A. We set a flag somewhere in redux/zustand/context when the google maps script is loaded. The placement of script tag will depend on the use cases like:

B. Wherever we are using usePlacesAutoComplete, we delay initialization of the hook based on our flag:

const isMapScriptLoaded = useMapStore((state) => state.isMapScriptLoaded);

const { init } = usePlacesAutocomplete({ initOnMount: false });

useEffect(() => {
    if (isMapScriptLoaded) {
        init();
    }
}, [isMapScriptLoaded]);

The above example uses a zustand store, same can be implemented for redux or context as well.

waldothedeveloper commented 2 years ago

Hey there: @paularah What I have on my NextJS app v. 12.2.5 and seems to be working is putting the Githubissues.

  • Githubissues is a development platform for aggregating issues.