The Geolocation API exposes navigator.geolocation.getCurrentPosition() and watchPosition(). Calling either one triggers the browser's native permission dialog. Ask only after a user gesture tied to a location feature, explain the benefit in a custom pre-prompt first, and always provide a manual location fallback (ZIP, postcode, city). A native denial is sticky per origin.
The pre-prompt is the only chance to explain the value before the irreversible native dialog. Specificity wins; vague benefits lose.
| Pre-Prompt Copy | Result | Why |
|---|---|---|
| "Allow location to improve your experience" | Fails | Vague benefit, sounds like data harvesting |
| "Find the nearest store with this item in stock" | Converts | Specific, time-bound, obvious value |
| "Get accurate delivery time for your address" | Converts | Direct exchange of value |
| "We use your location for analytics" | Fails | Benefit accrues to the site, not the user |
| "Show local weather alerts in your area" | Converts | Tangible feature tied to the request |
| Auto-prompt with no copy | Fails the automated audit + 85%+ denial | No context, no gesture, sticky denial |
getCurrentPosition on page load, in route handlers, or in analytics scripts.navigator.geolocation.getCurrentPosition().PERMISSION_DENIED, POSITION_UNAVAILABLE, TIMEOUT.document.querySelector('#use-location').addEventListener('click', async () => {
const accepted = await showPrePrompt({
title: 'Find the nearest store',
body: 'We use your location once to show stores within 10 miles. Nothing is stored.',
});
if (!accepted) return showZipInput();
navigator.geolocation.getCurrentPosition(
(pos) => renderNearbyStores(pos.coords),
(err) => {
if (err.code === err.PERMISSION_DENIED) {
showZipInput('Location blocked. Enter ZIP instead.');
} else {
showZipInput('Could not get location. Enter ZIP instead.');
}
},
{ timeout: 8000, maximumAge: 60_000 }
);
});// Permissions API lets you check state without triggering the prompt
async function canRequestLocation() {
if (!('permissions' in navigator)) return true;
const status = await navigator.permissions.query({ name: 'geolocation' });
return status.state !== 'denied'; // 'granted' or 'prompt' are both ok
}getCurrentPosition at the top of a route component or in useEffect(() => ..., []) with no gesture.watchPosition when getCurrentPosition is enough; continuous tracking is much harder to justify under GDPR.See also our guide on notification permission timing and why HTTPS is required for permission-gated APIs.
The audit "Avoids requesting the geolocation permission on page load" fails when getCurrentPosition or watchPosition runs without a user gesture, because the resulting denial is sticky and unrecoverable.
No. Chrome 50, Firefox 55, and all modern browsers restrict geolocation to secure contexts (HTTPS or localhost). On HTTP the API call resolves with POSITION_UNAVAILABLE or is blocked outright.
No. Once the user blocks geolocation for your origin, the browser will not show the prompt again. The user has to manually re-enable it in site settings, which almost never happens.
getCurrentPosition reads location once. watchPosition subscribes to updates until you call clearWatch. Use getCurrentPosition unless you genuinely need live tracking.
If you store, transmit, or process the location data, yes — GDPR Article 4 classifies precise location as personal data. The browser prompt alone is not GDPR consent; you also need a clear-language explanation and a lawful basis.
Manual ZIP / postcode / city input, or city-level IP geolocation for non-sensitive features like local weather. Never block the feature entirely.
Yes. Use navigator.permissions.query({ name: 'geolocation' }). It returns granted, denied, or prompt without triggering the dialog.
Yes, indirectly. A premature geolocation prompt drives high denial rates and quick bounces, which feed user-engagement signals reflected in Page Experience and the third-party usage data AI search engines like ChatGPT, Perplexity, and Google AI Overviews use to weight a source. Pages users abandon before reading are less likely to be cited as authoritative answers, regardless of underlying content quality.
Request geolocation only in direct response to a user gesture, after a custom pre-prompt that names a specific benefit, and always pair it with a manual ZIP or city fallback. Auto-prompting on page load fails automated audits and burns the only sticky answer the browser will ever give you — gate the call behind a button, check navigator.permissions before re-asking, and serve everything over HTTPS. Run a Greadme deep scan to find pages requesting geolocation prematurely and prioritize the ones costing you grant rates.