Geolocation API

W3C First Public Working Draft

This version:
https://www.w3.org/TR/2021/WD-geolocation-API-20210420/
Latest published version:
https://www.w3.org/TR/geolocation-API/
Latest editor's draft:
https://w3c.github.io/geolocation-api/
Test suite:
https://web-platform-tests.live/geolocation-API/
Editor:
Marcos Cáceres (W3C)
Former editor:
Andrei Popescu (Google Inc.)
Participate:
GitHub w3c/geolocation-api
File a bug
Commit history
Pull requests
Browser support:
caniuse.com

Abstract

The Geolocation API provides access to geographical location information associated with the hosting device.

Status of This Document

This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at https://www.w3.org/TR/.

The Devices and Sensors Working Group is updating this specification in the hope of making it a "living standard". As such, we've dropped the "Editions" and aim to continue publishing updated W3C Recommendations of this specification as we add new features or fix bugs.

This document was published by the Devices and Sensors Working Group as a First Public Working Draft. This document is intended to become a W3C Recommendation.

GitHub Issues are preferred for discussion of this specification.

Publication as a First Public Working Draft does not imply endorsement by the W3C Membership.

This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.

This document was produced by a group operating under the W3C Patent Policy. W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.

This document is governed by the 15 September 2020 W3C Process Document.

1. Introduction

This section is non-normative.

The Geolocation API defines a high-level interface to location information associated only with the device hosting the implementation. Common sources of location information include Global Positioning System (GPS) and location inferred from network signals such as IP address, RFID, WiFi and Bluetooth MAC addresses, and GSM/CDMA cell IDs, as well as user input. The API itself is agnostic of the underlying location information sources, and no guarantee is given that the API returns the device's actual location.

If an end user grants permission, the Geolocation API:

1.1 Scope

This section is non-normative.

This specification is limited to providing a scripting API for retrieving geographic position information associated with a hosting device. The geographic position information is provided in terms of World Geodetic System coordinates [WGS84]. It does not include providing a markup language of any kind, nor does not include defining a new URL scheme for building URLs that identify geographic locations.

1.2 Changes since last publication

This section is non-normative.

Since publication of the Second Edition in 2016, this specification has received the following changes:

See the commit history for a complete list of changes.

2. Examples

This section is non-normative.

The API is designed to enable both "one-shot" position requests and repeated position updates. The following examples illustrate common use cases.

2.1 Get current position

This section is non-normative.

Request the user's current location. If the user allows it, you will get back a position object.

2.2 Watch a position

This section is non-normative.

Request the ability to watch user's current location. If the user allows it, you will get back continuous updates of the user's position.

2.3 Stop watching a position

This section is non-normative.

Stop watching for position changes by calling the clearWatch() method.

2.4 Handling errors

This section is non-normative.

When an error occur, the second argument of the watchPosition() or getCurrentPosition() method gets called with a GeolocationPositionError error, which can help you figure out what might have gone wrong.

2.5 Using maximumAge as cache control

This section is non-normative.

By default, the API always attempts to return a cached position so long as it has a previously acquired position. In this example, we accept a position whose age is no greater than 10 minutes. If the user agent does not have a fresh enough cached position object, it automatically acquires a new position.

2.6 Using timeout

If you require location information in a time sensitive manner, you can use the PositionOptions timeout member to limit the amount of time you are willing to wait to acquire a position.

2.7 Enabling the API in third-party contexts

This section is non-normative.

The default allowlist of ["self"] allows Geolocation API usage in same-origin nested frames but prevents third-party content from using the API.

Third-party usage can be selectively enabled by adding allow="geolocation" attribute to an iframe element:

Alternatively, the API can be disabled in a first-party context by specifying the a HTTP response header:

See Permissions Policy for more details about the Permissions-Policy HTTP header.

3. Privacy and security considerations

This section is non-normative.

The API defined in this specification is used to retrieve the geographic location of a hosting device. In almost all cases, this information also discloses the location of the user of the device, thereby potentially compromising the user's privacy.

3.1 Privacy considerations for recipients of location information

This section is non-normative.

Note: Developers' responsibility with this sensitive data

This section applies to "recipients", which generally means developers utilizing the Geolocation API. Although it's impossible for user agent, or this specification, to enforce these requirements, developers need to read this section carefully and do their best to adhere to the suggestions below. Developers need to be aware that there might be privacy laws in their jurisdictions that can govern the usage and access to users' location data.

Recipients ought to only request position information when necessary, and only use the location information for the task for which it was provided to them. Recipients ought to dispose of location information once that task is completed, unless expressly permitted to retain it by the user. Recipients need to also take measures to protect this information against unauthorized access. If location information is stored, users need to be allowed to update and delete this information.

The recipient of location information need to refrain from retransmitting the location information without the user’s express permission. Care needs to be taken when retransmitting and the use of encryption is encouraged.

Recipients ought to clearly and conspicuously disclose the fact that they are collecting location data, the purpose for the collection, how long the data is retained, how the data is secured, how the data is shared if it is shared, how users can access, update and delete the data, and any other choices that users have with respect to the data. This disclosure needs to include an explanation of any exceptions to the guidelines listed above.

3.2 Implementation considerations

This section is non-normative.

Implementers are advised to consider the following aspects that can negatively affect the privacy of their users: in certain cases, users can inadvertently grant permission to the user agent to disclose their location to websites. In other cases, the content hosted at a certain URL changes in such a way that the previously granted location permissions no longer apply as far as the user is concerned. Or the users might simply change their minds.

Predicting or preventing these situations is inherently difficult. Mitigation and in-depth defensive measures are an implementation responsibility and not prescribed by this specification. However, in designing these measures, implementers are advised to enable user awareness of location sharing, and to provide access to user interfaces that enable revocation of permissions.

5. Geolocation interface and callbacks

WebIDL[Exposed=Window]
interface Geolocation {
  undefined getCurrentPosition (
    PositionCallback successCallback,
    optional PositionErrorCallback? errorCallback = null,
    optional PositionOptions options = {}
  );

  long watchPosition (
    PositionCallback successCallback,
    optional PositionErrorCallback? errorCallback = null,
    optional PositionOptions options = {}
  );

  undefined clearWatch (long watchId);
};

callback PositionCallback = undefined (
  GeolocationPosition position
);

callback PositionErrorCallback = undefined (
  GeolocationPositionError positionError
);

5.1 Internal slots

Instances of Geolocation are created with the internal slots in the following table:

Internal slot Description
[[cachedPosition]] A GeolocationPosition, initialized to null. It's a reference to the last acquired position and serves as a cache. A user agent MAY evict [[cachedPosition]] by resetting it to null at any time for any reason.
[[watchTasks]] Initialized as an empty set of unsigned long items, which represent the identifier for timed task.

5.2 getCurrentPosition() method

When getCurrentPosition() is invoked, the user agent MUST:

  1. Request position, passing successCallback, errorCallback, options, and (repeats) false.
  2. Return undefined.

5.3 watchPosition() method

When watchPosition() is invoked, the user agent MUST:

  1. Let watchId be request position, passing successCallback, errorCallback, options, and (repeats) true.
  2. Return watchId.

5.4 clearWatch() method

When clearWatch() is invoked, the user agent MUST:

  1. If this's [[watchTasks]][watchId] exists, remove this's [[watchTasks]][watchId].

5.5 Request position

Request position by passing a PositionCallback successCallback, a PositionErrorCallback? errorCallback, PositionOptions options, a boolean repeats, and optionally (and only if repeats is true) a previous id.

  1. Let watchTasks be this's [[watchTasks]].
  2. Acquire a watch id.
    1. If previous id was provided, let watchId be previous id; Otherwise, let watchId be an implementation-defined long that is greater than or equal to zero.
    2. Append watchId to watchTasks.
    3. Return watchId and continue in parallel.
  3. Do security check.
    1. If the environment settings object is a non-secure context, then:
      1. Call back with error errorCallback and PERMISSION_DENIED.
      2. Remove watchId from watchTasks.
      3. Terminate this algorithm.
  4. Wait for document to become visible.
    1. Let document be the current settings object's associated Document.
    2. If document is hidden, wait for the document to become visible.
  5. Check permission passing errorCallback. If the check return failure:
    1. Remove watchId from watchTasks.
    2. Terminate this algorithm.
  6. Acquire position.
    1. Let acquisitionTime be a new DOMTimeStamp that represents now in milliseconds, using 01 January, 1970 UTC as the epoch.
    2. If options.maximumAge is greater than 0, and cachedPosition is not null:
      1. Let cachedPosition be this's [[cachedPosition]].
      2. Let cacheTime be acquisitionTime minus the value of options.maximumAge member.
      3. If cachedPosition's timestamp's value is greater than cacheTime, and cachedPosition.[[isHighAccuracy]] equals options.enableHighAccuracy:
        1. Queue a microtask to invoke successCallback with cachedPosition.
        2. Go to determine repetition steps below.
    3. Let timeout be a new timed task that runs in options.timeout milliseconds after acquisitionTime, which performs the following sub-steps:
      Note: Immediate cancellation
      1. If the entry for timerId in the list of active timers has been cleared, then abort these steps.
      2. Call back with error with errorCallback and TIMEOUT.
    4. Let timerId be an implementation-defined identifier that represents timeout.
    5. Add timerId to the list of active timers.
    6. Try to acquire the device's position, optionally taking into consideration the value of options.enableHighAccuracy:
      1. If acquiring a position succeeds:
        1. Let position be a new GeolocationPosition passing acquisitionTime and options.enableHighAccuracy.
        2. Set this's [[cachedPosition]] to position.
        3. Queue a microtask to invoke successCallback with position.
      2. If acquiring a position fails:
        1. Call back with error passing errorCallback and POSITION_UNAVAILABLE.
    7. Clear timerId from the list of active timers.
  7. Determine repetition.
    1. If repeats is false:
      1. Remove watchId from watchTasks.
      2. Terminate this algorithm.
  8. Wait for a significant change of geographic position. What constitutes a significant change of geographic position is left to the implementation. A user agents MAY impose a rate limit on the frequency position changes.
  9. If watchTasks contains watchId, then:
    1. Request position passing successCallback, errorCallback, options, repeats, and watchId.

5.6 Check permission

When instructed to check permission, given an PositionErrorCallback? errorCallback:

  1. Let permission be request permission to use "geolocation".
  2. If permission is "denied", then:
    1. Call back with error errorCallback and PERMISSION_DENIED.
    2. Return failure.

5.7 Call back with error

When instructed to call back with error, given an PositionErrorCallback? callback and an unsigned short code:

  1. If callback is null, return.
  2. Let error be a a newly created GeolocationPositionError instance whose code attribute is initialized to code.
  3. Invoke callback with error.

6. PositionOptions dictionary

WebIDLdictionary PositionOptions {
  boolean enableHighAccuracy = false;
  [Clamp] unsigned long timeout = 0xFFFFFFFF;
  [Clamp] unsigned long maximumAge = 0;
};

6.1 enableHighAccuracy member

The enableHighAccuracy member provides a hint that the application would like to receive the most accurate location data. The intended purpose of this member is to allow applications to inform the implementation that they do not require high accuracy geolocation fixes and, therefore, the implementation MAY avoid using geolocation providers that consume a significant amount of power (e.g. GPS).

Note: A word of warning about enableHighAccuracy

6.2 timeout member

The timeout member denotes the maximum length of time, expressed in milliseconds, before acquiring a position expires.

The time spent waiting for the document to become visible and for obtaining permission to use the API is not included in the period covered by the timeout member. The timeout member only applies when acquiring a position begins.

6.3 maximumAge member

The maximumAge member indicates that the web application is willing to accept a cached position whose age is no greater than the specified time in milliseconds.

7. GeolocationPosition interface

WebIDL[Exposed=Window, SecureContext]
interface GeolocationPosition {
  readonly attribute GeolocationCoordinates coords;
  readonly attribute DOMTimeStamp timestamp;
};

7.1 coords attribute

The coords attribute contains geographic coordinates.

7.2 timestamp attribute

The timestamp attribute represents the time when the geographic position of the device was acquired.

7.3 Internal slots

Instances of GeolocationPositionError are created with the internal slots in the following table:

Internal slot Description
[[isHighAccuracy]] A boolean that records the value of the enableHighAccuracy member when this GeolocationPosition is created.

8. GeolocationCoordinates interface

WebIDL[Exposed=Window, SecureContext]
interface GeolocationCoordinates {
  readonly attribute double accuracy;
  readonly attribute double latitude;
  readonly attribute double longitude;
  readonly attribute double? altitude;
  readonly attribute double? altitudeAccuracy;
  readonly attribute double? heading;
  readonly attribute double? speed;
};

8.1 latitude, longitude, and accuracy attributes

The latitude and longitude attributes are geographic coordinates specified in decimal degrees.

The accuracy attribute denotes the accuracy level of the latitude and longitude coordinates in meters (e.g., 65 meters).

8.2 altitude and altitudeAccuracy attributes

The altitude attribute denotes the height of the position, specified in meters above the [WGS84] ellipsoid.

The altitudeAccuracy attribute represents the altitude accuracy in meters (e.g., 10 meters).

8.3 heading attribute

The heading attribute denotes the direction of travel of the hosting device and is specified in degrees, where 0° ≤ heading < 360°, counting clockwise relative to the true north.

8.4 speed attribute

The speed attribute denotes the magnitude of the horizontal component of the hosting device's current velocity in meters per second.

8.5 Constructing a GeolocationPosition

A new GeolocationPosition is constructed with DOMTimeStamp timestamp and boolean isHighAccuracy by performing the following steps:

  1. Let coords be a newly created GeolocationCoordinates instance:
    1. Initialize coord's latitude attribute to a geographic coordinate in decimal degrees.
    2. Initialize coord's longitude attribute to a geographic coordinate in decimal degrees.
    3. Initialize coord's accuracy attribute to a non-negative real number. The value SHOULD correspond to a 95% confidence level with respect to the longitude and latitude values.
    4. Initialize coord's altitude attribute in meters above the [WGS84] ellipsoid, or null if the implementation cannot provide altitude information.
    5. Initialize coord's altitudeAccuracy attribute as non-negative real number, or to null if the implementation cannot provide altitude information. If the altitude accuracy information is provided, it SHOULD correspond to a 95% confidence level.
    6. Initialize coord's speed attribute to a non-negative real number, or as null if the implementation cannot provide speed information.
    7. Initialize coord's heading attribute in degrees, or null implementation cannot provide heading information. If the hosting device is stationary (i.e. the value of the speed attribute is 0), then initialize the heading to NaN.
  2. Return a newly created GeolocationPosition instance with its coords attribute initialized to coords and timestamp attribute initialized to timestamp, and its [[isHighAccuracy]] internal slot set to isHighAccuracy.

9. GeolocationPositionError interface

WebIDL[Exposed=Window]
interface GeolocationPositionError {
  const unsigned short PERMISSION_DENIED = 1;
  const unsigned short POSITION_UNAVAILABLE = 2;
  const unsigned short TIMEOUT = 3;
  readonly attribute unsigned short code;
  readonly attribute DOMString message;
};

9.1 Constants

PERMISSION_DENIED (numeric value 1)
Request position failed because the user denied permission to use the API.
POSITION_UNAVAILABLE (numeric value 2)
Acquire a position failed.
TIMEOUT (numeric value 3)
The length of time specified by the timeout member has elapsed before the user agent could successfully acquire a position.

9.2 code attribute

The code attribute returns the value it was initialized to (see § 9.1 Constants for possible values).

9.3 message attribute

The message attribute is a developer-friendly textual description of the code attribute.

Note: Don't show .message to users!

10. Permissions policy

The Geolocation API defines a policy-controlled feature identified by the string "geolocation". Its default allowlist is ["self"].

11. Conformance

As well as sections marked as non-normative, all authoring guidelines, diagrams, examples, and notes in this specification are non-normative. Everything else in this specification is normative.

The key words MAY, MUST, and SHOULD in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.

A. IDL Index

WebIDLpartial interface Navigator {
  [SameObject] readonly attribute Geolocation geolocation;
};

[Exposed=Window]
interface Geolocation {
  undefined getCurrentPosition (
    PositionCallback successCallback,
    optional PositionErrorCallback? errorCallback = null,
    optional PositionOptions options = {}
  );

  long watchPosition (
    PositionCallback successCallback,
    optional PositionErrorCallback? errorCallback = null,
    optional PositionOptions options = {}
  );

  undefined clearWatch (long watchId);
};

callback PositionCallback = undefined (
  GeolocationPosition position
);

callback PositionErrorCallback = undefined (
  GeolocationPositionError positionError
);

dictionary PositionOptions {
  boolean enableHighAccuracy = false;
  [Clamp] unsigned long timeout = 0xFFFFFFFF;
  [Clamp] unsigned long maximumAge = 0;
};

[Exposed=Window, SecureContext]
interface GeolocationPosition {
  readonly attribute GeolocationCoordinates coords;
  readonly attribute DOMTimeStamp timestamp;
};

[Exposed=Window, SecureContext]
interface GeolocationCoordinates {
  readonly attribute double accuracy;
  readonly attribute double latitude;
  readonly attribute double longitude;
  readonly attribute double? altitude;
  readonly attribute double? altitudeAccuracy;
  readonly attribute double? heading;
  readonly attribute double? speed;
};

[Exposed=Window]
interface GeolocationPositionError {
  const unsigned short PERMISSION_DENIED = 1;
  const unsigned short POSITION_UNAVAILABLE = 2;
  const unsigned short TIMEOUT = 3;
  readonly attribute unsigned short code;
  readonly attribute DOMString message;
};

B. Index

B.1 Terms defined by this specification

B.2 Terms defined by reference

C. Acknowledgments

This section is non-normative.

This specification builds upon earlier work in the industry, including research by Aza Raskin, Google Gears Geolocation API, and LocationAware.org.

Thanks also to Alec Berntson, Alissa Cooper, Steve Block, Greg Bolsinga, Lars Erik Bolstad, Aaron Boodman, Dave Burke, Chris Butler, Max Froumentin, Shyam Habarakada, Marcin Hanclik, Ian Hickson, Brad Lassey, Angel Machin, Cameron McCormack, Daniel Park, Stuart Parmenter, Olli Pettay, Chris Prince, Arun Ranganathan, Carl Reed, Thomas Roessler, Dirk Segers, Allan Thomson, Martin Thomson, Doug Turner, Erik Wilde, Matt Womer, and Mohamed Zergaoui.

D. References

D.1 Normative references

[HTML]
HTML Standard. Anne van Kesteren; Domenic Denicola; Ian Hickson; Philip Jägenstedt; Simon Pieters. WHATWG. Living Standard. URL: https://html.spec.whatwg.org/multipage/
[infra]
Infra Standard. Anne van Kesteren; Domenic Denicola. WHATWG. Living Standard. URL: https://infra.spec.whatwg.org/
[page-visibility-2]
Page Visibility Level 2. Ilya Grigorik; Arvind Jain; Jatinder Mann. W3C. 17 October 2017. W3C Proposed Recommendation. URL: https://www.w3.org/TR/page-visibility-2/
[Permissions]
Permissions. Mounir Lamouri; Marcos Caceres; Jeffrey Yasskin. W3C. 20 July 2020. W3C Working Draft. URL: https://www.w3.org/TR/permissions/
[Permissions-Policy]
Permissions Policy. Ian Clelland. W3C. 16 July 2020. W3C Working Draft. URL: https://www.w3.org/TR/permissions-policy-1/
[RFC2119]
Key words for use in RFCs to Indicate Requirement Levels. S. Bradner. IETF. March 1997. Best Current Practice. URL: https://tools.ietf.org/html/rfc2119
[RFC8174]
Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words. B. Leiba. IETF. May 2017. Best Current Practice. URL: https://tools.ietf.org/html/rfc8174
[secure-contexts]
Secure Contexts. Mike West. W3C. 15 September 2016. W3C Candidate Recommendation. URL: https://www.w3.org/TR/secure-contexts/
[WebIDL]
Web IDL. Boris Zbarsky. W3C. 15 December 2016. W3C Editor's Draft. URL: https://heycam.github.io/webidl/
[WGS84]
National Imagery and Mapping Agency Technical Report 8350.2, Third Edition. National Imagery and Mapping Agency. 3 January 2000.