Mapping software has existed for years on machines connected to the internet, be that in apps or websites. (Remember printing out directions from Mapquest?)
On mobile (read phones and tablets), we have Google Maps, Apple Maps or Waze. Desktop is trickier because neither Windows or Linux come with default, client-side mapping software. macOS, however, does come with (Apple) Maps.
It would be nice if, on websites, we could create one link that had enough data in it that it could open a default app or website for people to get driving directions. In other words, not a link to Google Maps. Not a link to Apple Maps. Just enough metadata for the browser to open the mapping software of the user’s choice.
Defining the Problem
First, some definitions.
URL, an acronym that stands for Uniform Resource Locator, best known as web links. URLs have the following format:
[scheme]://[host]/[path]?[query]#[fragment]
If we take a web address, say https://apple.com
, we can see that there is a scheme (https
) and a host (apple.com
). We can omit a path because web servers will provide a default path even if one is not specified. But if we want a specific resource from the domain, then we would add the path. For example, if we want to look at the iPhone page, we would specify https://www.apple.com/iphone/
.
It turns out that URLs are a highly familiar form of a URI or Uniform Resource Identifier. A URI is a string of characters that identifies a resource, either by its location, name, or both, in a standardized way. URIs are structured like this:
[scheme]:[scheme-specific-part][#fragment]
As you can see, the format of a URI is a more generic form of a URL.
URI Schemes in Action
With a URL, the scheme part of the URI is also the protocol that is to be used e.g. http
or https
. Web browsers handle both of these protocols because web sites run on the Hype*text **Transfer **P*rotocol. HTTP protocol; HTTPS adds encryption or the "security" the "S" stands for in the acronym.
It turns out that there are URIs that are useful for other things like creating a link to a phone number or an email address. For example
<a href=”tel:2595556455”>Might Actually be a Valid Phone Number</a>
will render like this: Might Actually be a Valid Phone Number. If you were to click or tap the link, your device will try to place a phone call to 2595556455
with some kind of telephony app. For iOS, this would be the phone app that comes pre-installed on the phone. (You can change the default to FaceTime; Zoom is also an option if installed, but Signal is not.) There are also default dialers for Androids of all kinds. And it's possible that you could default to an app like Signal.
On macOS, FaceTime will open if you click on a link that has a tel:
URI scheme.
<a href=”mailto:janedoe@spamspamspam.com”>Totally Legit Email</a>
will render like this: Totally Legit Email
If you were to click or tap that link, your default email client would open on both desktop and mobile.
What if there was a URI scheme that could do the same for addresses?
The loc:
URI Scheme
What many web programmers don’t know is that there is a geolocation URI scheme that has been defined since 2010. Here are two examples:
<a href=”geo:112.0,-112.0;u=35”>Example of a Geolocation Tag</a>
<a href="geo:0,0?q=1600+Pennsylvania+Ave+NW,+Washington,+DC+20500" rel="noopener">1600 Pennsylvania Ave NW, Washington, DC 20500</a>
In the first example, what follows geo:
is latitude and longitude coordinates with an optional “uncertainty” radius parameter defined by the u=35
. In the second example, we see we can zero out the lat and long and use a mailing address instead.
This seems like nirvana, one geolocation URI scheme to rule them all!
Unfortunately, not all is well in Elsinore.
It Doesn't Really Work
The only device that seems to support it half way decently, is a major browser (i.e. Firefox) on an Android phone.
The major reason that geo:
URI schemes don't work is that the browsers don't register handlers for the URI schemes.
We'll show you a lame workaround towards the end of this post that relies on browsers not handling the loc:
URI scheme throwing an error that can be handled in a try/catch
, but it turns out even that doesn't work.
Firefox, Chrome, and Safari don’t even recognize the thing, apparently
Firefox
<a>
with a geo:
URI scheme
The fact that this is not an error means that it cannot be handled simply by a try / catch fallback on Firefox. It must have a more robust device agent checking solution that “fixes” Firefox's shortcomings. The good news is that Firefox's marketshare is dwindling, so this browser may not have to be supported for long.
Chrome
<a>
with a geo:
URI scheme
You might expect that Chrome would open a new tab or window to Google Maps with the specified latitude and longitude or physical address. Instead, the behavior is a silent console error with no message presented to the end-user.
Safari
Safari's behavior on both desktop is even more baffling, especially given that Safari only runs on Apple's OSes and Apple has their own, first-party mapping software!
Safari Desktop
<a>
with a geo:
URI scheme
On the desktop, at least Safari gives a browser alert in addition to throwing an error. But, as pointed out above, this makes absolutely no sense–why doesn't Apple at lest register geo:
with Safari and either ask or attempt to open the location in Apple Maps?
Perhaps Apple has avoided doing this to avoid an anti-trust/anti-competition lawsuit. This seems fixable with a setting, but as we will see, even on mobile Apple hasn't properly solve this problem.
Safari Mobile
<a>
with a geo:
URI scheme
Tapping on a link that has a geo:
URI scheme on iOS 18.5 on an iPhone 16 Pro doesn't try to open Apple Maps nor Google Maps, both of which are installed. Instead, mobile Safari is registered to open location links with Google Earth!
To add insult to injury, maps isn't a category that you can set a default app for, at least not in Default Apps:
Apple has, in times past, sometimes hidden default app settings in Apple's setting for that particular app. For example, you'd go to Safari's settings to change the default web browser. There is no such setting in the (Apple) Maps settings. (Note: I'm not showing the Maps settings here because it's several screens long and there is no default setting in the list of Maps settings.)
A Workaround
As promised, here is a workaround. It is a React component that detects browsers that do support loc:
and replaces the anchor with a link to Google Maps if the browser doesn't support the loc:
URI scheme. (Note: This code doesn't know about browser's capabilities; rather, it assumes the programmer knows which browsers do and don't support loc:
URI schemes.)
const AddressLink = ({ street, city, state, zip, }: { street: string; city: string; state: string; zip: string; }) => { if (!street?.trim() || !city?.trim() || !state?.trim() || !zip?.trim()) { return <address>Invalid address</address>; } const address = `${street.trim().replace(/\.$/, "")}, ${city .trim() .replace(/\.$/, "")}, ${state.trim().replace(/\.$/, "")} ${zip.trim()}`; const encoded_address = encodeURIComponent(address).replace(/%20/g, "+"); const geoAddress = `geo:0,0?q=${encoded_address}`; const fallbackAddress = `https://www.google.com/maps/search/?api=1&query=${encoded_address}`; // this will need to be updated for any new mobile devices that exist. // it is a regex that tests the current agent against all the agents listed. function supportsGeoScheme() { return /Android|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test( navigator.userAgent ); } const handleClick = (e: React.MouseEvent) => { if (supportsGeoScheme()) { window.location.href = geoAddress; // Attempt geo: } else { e.preventDefault(); window.location.href = fallbackAddress; // Fallback to Google Maps } }; return ( <address> <a href={geoAddress} onClick={handleClick} rel="noopener noreferrer"> {address} </a> </address> ); }; export default AddressLink;
If this post was helpful, educational or entertaining, please consider converting that help, education or entertainment value into a number and returning it to us:
Justin Morrow (github - LinkedIn - X) contributed to this blog post and will receive partial compensation from donations.
Top comments (0)