ScreenshotNeo

BlogHow-to

How to Test Geolocation in a Browser

Use Chrome DevTools to test browser geolocation, permissions, errors, and fallback behavior. Learn what a simulated location can—and cannot—verify.

By the ScreenshotNeo team4 October 20269 min read

To test a website’s browser geolocation in Chrome, open DevTools, show the Sensors panel, and choose a preset city, enter custom coordinates, or set the location to unavailable. Then trigger the website’s location action and verify both the successful result and its fallback behavior. This changes the location exposed to the page by the browser; it does not change your IP address or prove how a server, CDN, or third-party service handles IP-based location.

Test a location in Chrome DevTools

  1. Serve the page over HTTPS and open it in Chrome. Geolocation is restricted to secure contexts.
  2. Open DevTools. Open the Command Menu with Command+Shift+P on macOS or Control+Shift+P on Windows, Linux, or ChromeOS.
  3. Type Sensors, select Show Sensors, and press Enter.
  4. In the Sensors panel, open the Geolocation list. Choose a preset city, enter custom latitude and longitude, or choose Location unavailable.
  5. Return to the page and trigger its usual location action. Check the rendered result, not just the coordinates in DevTools.
  6. Repeat with the location unavailable and with permission denied so you can check the app’s error messages and fallback.

Chrome’s Sensors panel provides preset cities, custom coordinates, and an unavailable-location setting. See the Chrome DevTools Sensors documentation.

Make a minimal geolocation test page

Use this standalone page to confirm that the browser returns the coordinates supplied through DevTools and to see the API’s error code and message. Save it as geolocation-test.html, serve it from an HTTPS development environment, and open it in Chrome. A local secure context may also be available at localhost.

<!doctype html>
<html lang="en">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Geolocation test</title>
<h1>Geolocation test</h1>
<button id="locate">Get my location</button>
<pre id="result" aria-live="polite">Choose a location and press the button.</pre>
<script>
const result = document.querySelector('#result');
document.querySelector('#locate').addEventListener('click', () => {
  if (!('geolocation' in navigator)) {
    result.textContent = 'Geolocation is not available in this browser.';
    return;
  }

  result.textContent = 'Requesting location…';
  navigator.geolocation.getCurrentPosition(
    position => {
      const { latitude, longitude, accuracy } = position.coords;
      result.textContent = JSON.stringify({
        latitude,
        longitude,
        accuracyMeters: accuracy,
        timestamp: new Date(position.timestamp).toISOString()
      }, null, 2);
    },
    error => {
      const names = {
        1: 'PERMISSION_DENIED',
        2: 'POSITION_UNAVAILABLE',
        3: 'TIMEOUT'
      };
      result.textContent = `${names[error.code] ?? 'UNKNOWN'} (${error.code}): ${error.message}`;
    },
    { enableHighAccuracy: false, timeout: 10000, maximumAge: 0 }
  );
});
</script>
</html>

Click the button after setting a Sensors location. The browser prompts for permission if the site has not already been granted or denied it. Reset the site’s location permission in Chrome’s site settings when you need to test the prompt again. The exact setting labels can vary by Chrome version.

Test the Geolocation API in application code

The API is exposed as navigator.geolocation. Check that it exists before calling it, request location in response to a clear user action, and handle the error callback. This example tests a one-time lookup and an ongoing position watch. It assumes the page runs in a secure context.

const status = document.querySelector('#location-status');
let watchId;

function getLocation() {
  if (!('geolocation' in navigator)) {
    status.textContent = 'This browser does not support geolocation.';
    return;
  }

  navigator.geolocation.getCurrentPosition(
    ({ coords, timestamp }) => {
      status.textContent =
        `Lat ${coords.latitude}, lon ${coords.longitude}; ` +
        `accuracy ${coords.accuracy} m; ` +
        `time ${new Date(timestamp).toISOString()}`;
    },
    error => {
      const messages = {
        1: 'Location permission was denied. You can enter a location manually.',
        2: 'The browser could not determine a location. Try again or enter one manually.',
        3: 'The location request timed out. Try again.'
      };
      status.textContent = messages[error.code] ?? 'Location could not be read.';
    },
    { enableHighAccuracy: false, timeout: 10000, maximumAge: 0 }
  );
}

function startWatching() {
  if (!('geolocation' in navigator)) {
    status.textContent = 'This browser does not support geolocation.';
    return;
  }

  watchId = navigator.geolocation.watchPosition(
    ({ coords }) => {
      status.textContent = `Lat ${coords.latitude}, lon ${coords.longitude}`;
    },
    error => {
      status.textContent = `Location update failed (${error.code}): ${error.message}`;
    },
    { enableHighAccuracy: false, timeout: 10000, maximumAge: 0 }
  );
}

function stopWatching() {
  if (watchId !== undefined) {
    navigator.geolocation.clearWatch(watchId);
    watchId = undefined;
  }
}

Add an element such as <p id="location-status"></p> to the page and connect getLocation(), startWatching(), and stopWatching() to suitable buttons. A watch can report successive positions; clear it when the feature no longer needs updates.

What to verify

Case How to exercise it What to check
Successful one-time lookup Choose a preset or custom location, allow permission, and trigger the page action. The page uses the returned coordinates and shows the expected location-specific result.
Changing position Start a watchPosition() flow, change the Sensors override, and observe updates. The interface updates appropriately and stops listening when the feature ends.
Permission denied Deny the browser prompt, or use a previously denied site permission. The page explains the problem and offers a useful next step, such as manual entry.
Position unavailable Select Location unavailable in Sensors. The app shows a useful fallback and does not treat missing coordinates as a valid location.
Timeout Exercise the request’s timeout path, or use a deliberately short timeout in a test build. The page allows retry or another way to continue.
Unsupported API Use a browser or test environment without navigator.geolocation, or stub it as absent. The page remains usable or explains the limitation.
Insecure context Open a non-secure test page where the browser does not expose geolocation. The page explains that location requires a secure context and gives a secure route to continue.
System location disabled Test on a device with operating-system location services disabled, if relevant to your users. The app handles a browser request that fails even when site permission appears allowed.

For a location-dependent feature, test the complete user journey: why the site asks, when the prompt appears, what happens after each result, and whether a non-location path remains available. The W3C specification says geolocation requires express permission before location data is shared with a web application. Its privacy guidance also recommends requesting location only when needed, using it for the stated task, protecting it, and explaining collection and retention. Read the W3C Geolocation specification and the practical web.dev guide to user location.

Understand what the simulated location proves

The browser Geolocation API is a high-level interface. Its underlying location source may use GPS, network signals, or user input, and the specification does not guarantee that a returned location is the device’s actual location. A DevTools override is useful for checking how a page behaves when the browser provides chosen coordinates.

It does not change the network’s IP address. If your backend, CDN, or an external service chooses a region from the client IP, test that signal separately with an appropriate network or server-side test. IP-derived estimates can be inaccurate, especially when a VPN or proxy is involved, as the web.dev location guide explains. Do not infer server-side geolocation behavior from a successful browser override.

Or skip the browser setup

If you need a screenshot of the page’s location-specific state, ScreenshotNeo can capture a URL with one GET request. It is a website screenshot API and MCP server from Yorker Media. It captures rendered page output; use the Chrome workflow above when you need to exercise a browser’s Geolocation API, permission prompt, or changing position.

See the ScreenshotNeo API documentation. For a screenshot of the target page, replace the example URL with your own:

curl -G "https://api.screenshotneo.com/v1/shot" \
  -d access_key=YOUR_API_KEY \
  --data-urlencode url=https://stripe.com \
  -o shot.webp
import requests

r = requests.get(
    "https://api.screenshotneo.com/v1/shot",
    params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
    timeout=90,
)
r.raise_for_status()
with open("shot.webp", "wb") as image:
    image.write(r.content)
const q = new URLSearchParams({
  access_key: 'YOUR_API_KEY',
  url: 'https://stripe.com'
});
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
const image = Buffer.from(await res.arrayBuffer());
await (await import('node:fs/promises')).writeFile('shot.webp', image);
  • Cookie and consent banners, newsletter popups, and chat widgets are removed before the shot; each cleanup step can be turned off.
  • Bot checks, blank pages, failed loads, timeouts, and cache hits are never billed. Responses identify page verdict and billing status in headers.
  • An MCP server lets AI agents using Claude, Cursor, or another MCP client take screenshots, inspect page information, and capture PDFs.
  • The free plan includes 1,000 screenshots a month with no card. Paid plans start at $5 for 3,000 screenshots.

Sign up for ScreenshotNeo and get 1,000 screenshots a month free, with no card.

Troubleshooting

Symptom Likely cause Fix
navigator.geolocation is missing The page is not in a supported secure context, or the browser does not expose the API. Serve the page over HTTPS, feature-detect the API, and provide a usable fallback.
Error code 1: permission denied The visitor denied the prompt, the site permission is blocked, or location access is disabled at the system level. Explain how to grant permission where appropriate, check device settings, and retain a manual alternative. Do not repeatedly prompt without a user action.
Error code 2: position unavailable The browser could not obtain a location, or DevTools is set to Location unavailable. Show a recoverable state, offer retry or manual entry, and verify your fallback using the DevTools override.
Error code 3: timeout The request did not produce a position within its timeout. Choose a timeout that suits the interaction, tell the user what happened, and allow another attempt or fallback.
The page keeps showing the old result The site may be reusing a cached position, or its UI did not request a fresh result. For a fresh test, set maximumAge: 0, trigger the location action again, and confirm the page updates its state.
Changing the Sensors location has no visible effect The page may only call getCurrentPosition() once, or it may not be listening for updates. Trigger a new one-time lookup after changing the override, or test a watchPosition() flow and clear its watch when finished.
Browser permission is allowed but lookup still fails Operating-system location settings may be off, or the position source may be unavailable. Check the device’s system location settings and test the position-unavailable path. Browser permission and system permission are separate layers.
The browser result is right but the server selects the wrong region The server is likely using IP-based location, which the browser override does not change. Test the server’s IP-based decision separately and inspect the signal it uses.

Performance, reliability, and privacy notes

  • Choose accuracy for the task. enableHighAccuracy is a request hint, not a guarantee of precision. Avoid asking for more precision than the feature needs.
  • Set request options deliberately. timeout limits how long the page waits, while maximumAge controls how old a cached position may be. Use maximumAge: 0 when a fresh reading matters; allow an older result when the feature can tolerate it.
  • Stop watches. Call clearWatch() when tracking is no longer needed so the page stops requesting updates.
  • Design for failure. Permission, secure-context, device settings, and position availability can all affect the result. Keep an alternate path where location is not essential.
  • Minimize sensitive data. Request location only for a clear feature, explain the reason, and handle and retain coordinates according to the needs you disclose to users.

The API exposes error codes for permission denied, position unavailable, and timeout; the W3C algorithm also treats a non-secure context as permission denied. Consult the specification when mapping behavior to application states.

FAQ

Does a Chrome location override change my IP address?

No. It changes the location exposed to the page through the browser’s geolocation interface. IP-based decisions need a separate test.

Can I test a permission prompt more than once?

Yes. Reset the site’s location permission in Chrome’s site settings, reload, and trigger the location action again. The browser may remember a previous choice.

Should a website ask for location as soon as it loads?

Ask in context, when the feature needs the location, and explain why. A user action makes that request easier to understand.

Does the DevTools override verify the user’s real device location?

No. It tests how the page responds to coordinates exposed by the browser. It does not validate a physical device’s location source or a server’s IP-based geolocation.