Fix Geolocation Request on Page Load
Requesting location permission the moment someone lands on your page is the fastest way to get denied. Users don't trust sites that ask for sensitive permissions without context.
What's Happening
Your JavaScript calls navigator.geolocation.getCurrentPosition() or navigator.geolocation.watchPosition() during page load - before the user has done anything that suggests they want location features. The browser shows a permission prompt immediately, the user reflexively clicks "Block," and now your location features are permanently broken for that visitor.
Lighthouse flags this because it's both bad UX and counterproductive. Studies show permission grant rates drop significantly when prompts appear without context.
Diagnose
DevTools Console
Lighthouse reports the source location in the audit details. You can also find it manually:
- Open DevTools > Sources
- Search all files (
Cmd/Ctrl+Shift+F) forgeolocation - Look for calls to
getCurrentPositionorwatchPosition - Check if they're inside event handlers (good) or top-level/immediately invoked (bad)
Common Patterns That Trigger This
// Bad: Runs on script load
navigator.geolocation.getCurrentPosition((pos) => {
console.log(pos.coords)
})
// Bad: Runs immediately when module loads
const position = await new Promise((resolve) => {
navigator.geolocation.getCurrentPosition(resolve)
})
// Bad: Inside DOMContentLoaded or load event
window.addEventListener('load', () => {
navigator.geolocation.getCurrentPosition(handlePosition)
})
Fix
1. Request After User Action
Move geolocation requests inside user-triggered event handlers:
Before (bad):
// Runs on page load
navigator.geolocation.getCurrentPosition(
position => showNearbyStores(position.coords),
error => console.error(error)
)
After (good):
document.querySelector('#find-stores-btn').addEventListener('click', () => {
navigator.geolocation.getCurrentPosition(
position => showNearbyStores(position.coords),
error => showLocationError(error)
)
})
The user clicks "Find stores near me," the prompt appears, and they understand why you're asking.
2. Show a Pre-Permission Prompt
For better UX, explain before the browser prompt appears:
const locationBtn = document.querySelector('#use-location')
locationBtn.addEventListener('click', async () => {
// Check current permission state
const permission = await navigator.permissions.query({ name: 'geolocation' })
if (permission.state === 'granted') {
// Already have permission, proceed
getLocation()
}
else if (permission.state === 'prompt') {
// Show custom UI explaining why
showLocationExplainer()
}
else {
// Denied - show alternative
showManualLocationInput()
}
})
function showLocationExplainer() {
const modal = document.querySelector('#location-explainer')
modal.showModal()
modal.querySelector('#confirm-location').addEventListener('click', () => {
modal.close()
getLocation()
}, { once: true })
}
function getLocation() {
navigator.geolocation.getCurrentPosition(
position => handleSuccess(position.coords),
error => handleError(error)
)
}
3. Provide a Fallback
Always have a non-location path:
function initStoreLocator() {
// Default: show all stores or ask for zip code
showAllStores()
// Enhance with location button
const locationBtn = document.querySelector('#use-my-location')
locationBtn.addEventListener('click', requestLocation)
}
function requestLocation() {
navigator.geolocation.getCurrentPosition(
pos => filterStoresByProximity(pos.coords),
() => showZipCodeInput() // Fallback on denial/error
)
}
Verify the Fix
- Clear site data (DevTools > Application > Clear site data)
- Reload the page
- No permission prompt should appear
- Interact with the feature that needs location
- Now the prompt should appear
Run Lighthouse again - the "Requests the geolocation permission on page load" audit should pass.
Common Mistakes
- Moving to DOMContentLoaded - Still runs automatically, still bad. The user must do something first.
- Using setTimeout to delay -
setTimeout(() => { geolocation... }, 5000)is still automatic. Lighthouse may not catch it, but users will still see an unexplained prompt. - Checking permissions then requesting - Even
navigator.permissions.query()followed by an automatic request is wrong. The permission check is fine; the automatic request isn't. - Third-party scripts - Analytics or mapping libraries sometimes request location on load. Check your dependencies and configure them to defer location requests.
Test Your Entire Site
Location requests might be buried in a script that only loads on certain pages. Unlighthouse scans every page on your site and flags any that trigger geolocation requests on load.
Related
- Notification Permission - Same pattern, different API
- Best Practices Overview