Fix Geolocation Request on Page Load

Stop requesting geolocation permission on page load. Users distrust sites that ask for location without context - tie requests to user actions instead.
Harlan WiltonHarlan Wilton3 min read Published

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:

  1. Open DevTools > Sources
  2. Search all files (Cmd/Ctrl+Shift+F) for geolocation
  3. Look for calls to getCurrentPosition or watchPosition
  4. 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

  1. Clear site data (DevTools > Application > Clear site data)
  2. Reload the page
  3. No permission prompt should appear
  4. Interact with the feature that needs location
  5. 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.