ScreenshotNeo

BlogGuides

Geolocation API Examples and Usage in JavaScript and Python

Learn browser geolocation in JavaScript and server-side location requests in Python, with complete code, errors, privacy, and deployment guidance.

By the ScreenshotNeo team1 October 20268 min read

JavaScript and Python use different geolocation models. In a browser, JavaScript calls navigator.geolocation and the user grants permission. Python does not have that browser object; a Python program usually sends an HTTPS request to a hosted geolocation service with Wi-Fi, cell-tower, or IP-related inputs.

The browser result is an estimate. The W3C specification says that the API is independent of the underlying location sources and does not guarantee that the returned point is the device’s actual location. Treat latitude, longitude, and accuracy as uncertain data, not as GPS-grade truth.

This guide covers one-time and continuous browser location, a documented Python request to Google’s Geolocation API, equivalent cURL and Node.js requests, privacy and billing considerations, error handling, and production troubleshooting.

1. JavaScript: get a device’s current position

Check for browser support, call getCurrentPosition(), read the coordinates, and handle permission or service errors.

<button id='locate'>Use my location</button>
<pre id='output'></pre>

<script>
const button = document.querySelector('#locate');
const output = document.querySelector('#output');

button.addEventListener('click', () => {
  if (!('geolocation' in navigator)) {
    output.textContent = 'This browser does not provide geolocation.';
    return;
  }

  output.textContent = 'Requesting location permission…';

  navigator.geolocation.getCurrentPosition(
    (position) => {
      const { latitude, longitude, accuracy, altitude, heading, speed } = position.coords;
      output.textContent = JSON.stringify({
        latitude,
        longitude,
        accuracyMeters: accuracy,
        altitude,
        heading,
        speed,
        timestamp: new Date(position.timestamp).toISOString()
      }, null, 2);
    },
    (error) => {
      const messages = {
        1: 'Permission was denied.',
        2: 'The location could not be determined.',
        3: 'The location request timed out.'
      };
      output.textContent = messages[error.code] || error.message || 'Unknown geolocation error.';
    },
    {
      enableHighAccuracy: false,
      timeout: 10000,
      maximumAge: 60000
    }
  );
});
</script>

position.coords.latitude and position.coords.longitude are decimal degrees. accuracy is an estimated radius in meters; a larger value means more uncertainty. Other coordinate fields can be null.

How the options affect a request

Option Meaning Typical choice
enableHighAccuracy Requests a higher-accuracy source when available. It can take longer and use more battery. false unless the feature needs finer precision
timeout Maximum wait in milliseconds before the request fails. Set a finite value so the UI cannot wait forever
maximumAge Allows a cached position up to this age in milliseconds. Use a short value for navigation and a longer value for weather or regional content

Ask for the location in response to a clear user action and explain why it is needed. The browser controls the permission prompt; your code must still provide a useful denial and failure path.

2. JavaScript: track movement with watchPosition()

Use watchPosition() when the page needs repeated updates. Always retain the returned identifier and call clearWatch() when tracking ends.

let watchId = null;

function startTracking() {
  if (!('geolocation' in navigator)) {
    throw new Error('Geolocation is not supported by this browser.');
  }

  watchId = navigator.geolocation.watchPosition(
    (position) => {
      console.log({
        latitude: position.coords.latitude,
        longitude: position.coords.longitude,
        accuracy: position.coords.accuracy,
        timestamp: position.timestamp
      });
    },
    (error) => {
      console.error('Location watch failed:', error.code, error.message);
    },
    {
      enableHighAccuracy: true,
      timeout: 15000,
      maximumAge: 5000
    }
  );
}

function stopTracking() {
  if (watchId !== null) {
    navigator.geolocation.clearWatch(watchId);
    watchId = null;
  }
}

A watch may report the same position more than once or return updates with different accuracy. Throttle downstream work, such as map redraws or API writes, and stop the watch when the user leaves the feature or the page no longer needs updates.

3. Python: call a hosted geolocation service

Python cannot read a browser’s navigator.geolocation object. A server-side program must receive observations from a client or send network observations to a geolocation service. Google’s documented Geolocation API accepts a JSON request and returns a location object containing lat, lng, and an accuracy radius. Google describes this service as using cell-tower and Wi-Fi observations and directs browser users toward HTML5 geolocation when the browser can obtain the position itself.

You need an API key, an enabled API, billing configuration, and current quota and policy review before production use. Keep the key outside source control.

import os
import requests

api_key = os.environ['GOOGLE_MAPS_API_KEY']
endpoint = 'https://www.googleapis.com/geolocation/v1/geolocate'

payload = {
    'considerIp': True,
    'wifiAccessPoints': [
        {
            'macAddress': '01:23:45:67:89:AB',
            'signalStrength': -65,
            'signalToNoiseRatio': snr"
        }
    ]
}

response = requests.post(
    endpoint,
    params={'key': api_key},
    json=payload,
    timeout=15
)
response.raise_for_status()
data = response.json()

location = data['location']
print('latitude:', location['lat'])
print('longitude:', location['lng'])
print('accuracy_meters:', data['accuracy'])

Remove the illustrative Wi-Fi object when you do not have real observations. The request can also contain cell-tower and radio fields documented by Google. considerIp defaults to true; set it explicitly when that behavior matters to your application.

See the Google Geolocation API overview and its request and response reference for the current schema. The W3C Geolocation specification defines the browser interface.

4. Equivalent requests with cURL and Node.js

cURL

curl -X POST \
  'https://www.googleapis.com/geolocation/v1/geolocate?key=YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
    "considerIp": true,
    "wifiAccessPoints": [
      {
        "macAddress": "01:23:45:67:89:AB",
        "signalStrength": -65,
        "signalToNoiseRatio": 10
      }
    ]
  }'

Node.js 18+

const apiKey = process.env.GOOGLE_MAPS_API_KEY;

const response = await fetch(
  `https://www.googleapis.com/geolocation/v1/geolocate?key=${encodeURIComponent(apiKey)}`,
  {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      considerIp: true,
      wifiAccessPoints: [
        {
          macAddress: '01:23:45:67:89:AB',
          signalStrength: -65,
          signalToNoiseRatio: 10
        }
      ]
    })
  }
);

if (!response.ok) {
  throw new Error(`Geolocation request failed: ${response.status} ${await response.text()}`);
}

const result = await response.json();
console.log(result.location.lat, result.location.lng, result.accuracy);

5. Browser geolocation versus a hosted API

Concern Browser Geolocation API Hosted network-data API
Where data comes from The device and browser choose underlying sources. Your request supplies Wi-Fi, cell, radio, or related observations.
User interaction The browser asks for permission. Your server authenticates with an API credential; user permission is your application’s responsibility.
Interface navigator.geolocation.getCurrentPosition() or watchPosition(). An HTTPS request with JSON.
Uncertainty Read the returned accuracy value and communicate that it is an estimate. Read the service’s returned accuracy radius and validate whether the supplied observations are sufficient.
Cost and operations No hosted geolocation request is required, but your application still handles permissions and storage. Credentials, billing, quotas, rate limits, privacy terms, and provider policies apply.

Use the browser API when the location belongs to the person using your page and the browser can obtain it. Use a hosted service when a backend has network observations and needs an estimate without relying on a browser object. They are separate APIs and should not be presented as interchangeable implementations.

6. Privacy, security, and data handling

  • Request only the precision your feature needs. A regional forecast does not need the same handling as turn-by-turn navigation.
  • Explain why you collect location, how long you retain it, and who receives it.
  • Do not log raw coordinates, Wi-Fi identifiers, or API keys unnecessarily.
  • Keep hosted-service credentials on the server or in a secret manager. Restrict keys according to the provider’s current guidance.
  • Review Google’s current billing and pricing documentation, terms, quotas, and attribution requirements before deployment.
  • Treat every result as sensitive data. Apply access controls and delete stale records.

7. Troubleshooting

Symptom Likely cause Fix
navigator.geolocation is undefined The browser does not expose the API. Feature-detect it and provide a manual location fallback.
Permission denied The user rejected the prompt or a browser/site policy blocks access. Explain the feature, provide settings instructions, and let the user continue without location.
Timeout or position unavailable The device cannot obtain a fix before the timeout. Use a finite timeout, allow retry, and consider a cached result with maximumAge.
Coordinates look wrong The result is an estimate, stale cache, weak observations, or an incorrect coordinate interpretation. Inspect the timestamp and accuracy radius, validate latitude and longitude ranges, and avoid claiming exact precision.
Google returns an authentication or billing error Missing or invalid key, disabled API, billing not configured, or quota exhausted. Check the project configuration, key restrictions, enabled API, billing account, and quota dashboard.
Google returns a malformed request error Invalid JSON, unsupported field names, malformed MAC addresses, or incomplete tower data. Compare the payload with the current request schema and send only valid observations.
Server code exposes an API key The key was embedded in frontend code, committed, or printed in logs. Rotate it, load it from an environment variable or secret store, and restrict the replacement.

8. Performance, reliability, and cost

  • Browser latency: a fresh high-accuracy fix can take longer than a cached result. Set a timeout and show progress.
  • Battery: continuous high-accuracy watches can consume more power. Stop them when the user leaves the workflow.
  • Network resilience: queue or retry server requests carefully, with bounded exponential backoff. Do not duplicate writes when a retry may have succeeded.
  • Accuracy policy: reject or downgrade results whose accuracy radius is too large for the feature. Store the radius with the coordinate.
  • Hosted-service cost: Google requires billing and may apply quotas and current pricing. Check the provider’s live documentation before estimating spend.
  • Observability: record status codes, provider error codes, request duration, source type, and accuracy without retaining more personal data than necessary.

9. Or skip the browser setup

If your goal is to document or monitor a geolocation page, ScreenshotNeo can capture the page through one HTTP request. It is a screenshot API and MCP server, not a replacement for the browser or hosted geolocation APIs.

See the ScreenshotNeo API documentation for all options.

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)
open('shot.webp', 'wb').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}`);

Cookie banners, newsletter popups, and chat widgets are removed before the shot. Bot checks, blank pages, failed loads, and cache hits are not billed. An MCP server lets AI agents take screenshots. The free plan includes 1,000 screenshots a month with no card, and paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account.

10. FAQ

Does JavaScript geolocation require Google Maps?

No. navigator.geolocation is a browser API. A map is an optional display layer.

Can Python call navigator.geolocation?

No. Python must receive a position from a browser or call a separate server-side service.

Is the returned coordinate exact?

No. Read and store the supplied accuracy value, and design the feature around uncertainty.

Should I use getCurrentPosition() or watchPosition()?

Use the first for a one-time estimate and the second for movement updates. Stop a watch with clearWatch().

Can I publish a Google API key in frontend JavaScript?

Do not expose unrestricted credentials. Use the provider’s current key restrictions and keep server-side keys out of client bundles.