///
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
}