/// let scriptInjected = false function injectGoogleMapsApiScript (options = {}) { if (scriptInjected) return const optionsQuery = Object.keys(options) .map(k => `${encodeURIComponent(k)}=${encodeURIComponent(options[k])}`) .join('&') const url = `https://maps.googleapis.com/maps/api/js?${optionsQuery}` const script = document.createElement('script') script.setAttribute('src', url) script.setAttribute('async', '') script.setAttribute('defer', '') document.head.appendChild(script) scriptInjected = true } let apiPromise: Promise = null interface WindowWithGoogle extends Window { onGoogleMapsApiLoaded: () => void google: typeof google } export type GoogleMaps = typeof google.maps export function loadGoogleMapsApi () { if (typeof window === 'undefined') { throw new Error(`Google Maps API is only available in a browser context`) } const win = window as unknown as WindowWithGoogle if (!apiPromise) { apiPromise = new Promise((resolve, reject) => { try { win.onGoogleMapsApiLoaded = resolve injectGoogleMapsApiScript({ key: process.env.GOOGLE_API_KEY, callback: 'onGoogleMapsApiLoaded', libraries: process.env.GOOGLE_MAPS_LIBRARIES || 'places', v: 'beta', }) } catch (error) { reject(error) } }).then(() => win.google.maps) } return apiPromise }