Skip to main content
Track and retrieve a user’s real-time location using the device’s native GPS. Supports live updates to your frontend as the user moves, chronological replay on app reopen, optional server delivery on each point, one-off single reads, and distance-based triggers for high-accuracy use cases like running or navigation apps. A coarse long-range mode keeps recording while the app is backgrounded and survives the app being force-killed, which suits delivery tracking, trip logging, and region-crossing detection.
Location tracking runs in one of two modes. Continuous mode gives high-accuracy foreground updates. Long-range mode trades accuracy for background persistence that survives the app being force-killed. The mode is selected automatically from how far apart you ask points to be, covered below.

Installation


Despia Editor setup

Foreground tracking is enabled by default. Enable Background Location if your app needs to keep recording GPS while the user is in another app or has the screen locked, such as run trackers, delivery apps, or navigation. The long-range mode covered later also depends on this addon. If your use case is a one-time read or in-app tracking only, skip this setup entirely.
1

Open the Background Location addon

In the Despia Editor, navigate to App > Addons > Background Location.
2

Enable the addon

Toggle Background Location on. This grants your next build the background location capability the OS requires to let GPS keep running while your app is not in the foreground.
3

Rebuild your app

Trigger a fresh build from the Despia Editor. Background location requires native capabilities that have to be compiled into the app binary, so this cannot be applied over-the-air. After the rebuild, calls to location:// keep recording when the app is backgrounded.
Skipping the rebuild leaves background tracking inactive even if the toggle reads enabled. The location:// call will still work in the foreground, but as soon as the user backgrounds the app, the GPS stops recording silently. If your tracking sessions are missing the middle section, this is almost always the cause.

How it works

Call location:// to start the native GPS session and stoplocation:// to end it and retrieve the full session array. While tracking is active, every GPS point is delivered to window.onLocationChange in real time and stored locally on the device. When tracking stops, the complete session is returned to your JavaScript for processing. For a one-time position with no session, request a single fix instead, covered below.
To stop tracking and retrieve the session:

Parameters

location:// accepts the following query parameters.

Live updates with window.onLocationChange

Define window.onLocationChange before calling location:// to receive every GPS point in real time as the user moves. Each call receives a single location object with an active flag indicating whether tracking is still running.
When the app reopens during an active session, all buffered points are replayed into window.onLocationChange in chronological order so your frontend can reconstruct the full route without any additional code. Define the callback before calling location://, since any points emitted before it exists are lost.

Read a single location

For a one-time position read with no continuous tracking, request a single fix. The native GPS returns one snapshot and stops, which is ideal for stamping a location onto a form submission, a check-in, or a photo without starting a session.
A single read prompts for While-Using location permission if it has not been granted, never the Always permission that long-range tracking requires. The result is returned as a one-element session array in the same location object shape as a tracking point.

High-accuracy tracking

For use cases where each metre counts, combine movement with a long buffer to get distance-triggered updates as the primary signal and time-based updates as a heartbeat fallback.
Filter for high-accuracy points using horizontalAccuracy before calculating distances. A value below 10 indicates a precise fix. Keep movement below 50000 here, since 50000 or higher hands tracking to the coarse long-range mode.

Track long-range movement in the background

For coarse, long-distance use cases like delivery runs, trip logging, or detecting when a device crosses a region, set movement to 50000 (500 metres) or higher. This switches GPS into a low-power long-range mode that fires roughly every 500 metres of travel, keeps recording while the app is backgrounded, and survives the app being force-killed. When iOS relaunches your app to deliver the next point, Despia restores the session and resumes delivery on its own.
Long-range mode is driven by distance, not time. It fires on roughly every 500 metres of movement rather than on the buffer timer, so you will not receive points at a fixed interval while the device is stationary. The buffer value only throttles how often a point is posted once a fix arrives, not how often fixes happen. This mode requests Always location permission, since the OS needs it to wake a terminated app, and it depends on the Background Location addon being enabled in your build.
Always call stoplocation:// when a long-range session is finished. Despia persists the session so iOS can relaunch your app and continue delivery, and that persisted session is only cleared when you stop tracking. Skip the stop call and a later relaunch can silently resume tracking in the background.
For region or border detection, long-range mode does not watch specific boundaries. It wakes your app every 500 metres or so and posts the current position, and your server decides whether a line was crossed. With buffer=300, points arrive at most every five minutes, so a fast-moving device can pass a boundary before the next point lands. Lower buffer for tighter detection.

Server delivery

When server is set, each GPS point is POSTed to your endpoint as it is recorded. Server delivery, window.onLocationChange, and local session storage all run simultaneously and independently. Loss of network does not affect local storage or frontend callbacks.
Posts are fire-and-forget. A non-2xx response or a network error is not retried, so the point is dropped from the server stream while still kept in the local session. Make your endpoint idempotent and tolerant of out-of-order points, and sort by gpsTimestamp if order matters. The endpoint must be HTTPS. Each POST body matches the location object shape below.

Location object

Every location point, whether delivered via window.onLocationChange, the session array, or a server POST, has the following shape.
The callback delivers this object in two states, distinguished by active.
object
A live tracking point emitted while a session is running. Carries the full set of fields below. Use the coordinates for map rendering and the speed, course, and accuracy fields to drive live UI.
object
The final event of a session, emitted once when stoplocation:// is called. Same shape as a tracking point, but signals that tracking has ended so you can finalise the route or show a summary.
Battery percentage is sampled at every GPS point throughout the session, giving you a precise drain curve for the entire route rather than just a start and end value.

Tracking state

Use despia.locationTracking to reflect the current tracking state in your UI. It is set to true when location:// is called and false when stoplocation:// is called.

Calculate distance and analyse movement

Use the Haversine formula to calculate total distance from the session array after stopping.

Background and termination behaviour

Foreground tracking works with no addon and continues as long as the app is in the foreground. What happens once the app leaves the foreground depends on the mode. Once the addon is enabled, Despia manages the iOS blue location badge automatically and dismisses it as soon as stoplocation:// is called. On Android, Despia handles background location delivery across all major manufacturers including Samsung, Huawei, Xiaomi, and OnePlus, which apply aggressive background restrictions by default. No additional configuration is required. If you encounter missing server events on a specific Android device, contact location@despia.com.

Resources

NPM Package

despia-native