applink: A simple, stateless, privacy-protecting link redirection service for cross-platform apps

Posted by:

  • Avatar of Konstantin

    Konstantin

Consider a case where you have a multi-platform app, and you wish to provide a single link redirecting the user to the appropriate store for their platform. Applink is that simple and privacy-respecting redirect service.

There already exist many marketing tools and services which offer the ability to create redirect links based on rules like the user's device type, OS, browser, location, cohort etc. Unfortunately, such tools usually bring a certain level of data collection and tracking.

So what if you only wanted to redirect your user to the right store based on their device? No tracking, no data collection and no backend. Or perhaps, you'd like to host it yourself on your preferred static page provider like Netlify, GitHub Pages or Caddy powered website?

Meet applink! πŸŽ‰

Applink started as a tiny pet-project where a piece of client-side JavaScript would run to detect the user agent string and guess if it was an Apple device or an Android device.

While the script became a bit more sophisticated, its core design parameters remain unchanged. Applink is intended to execute entirely in the browser, without any server-side processing. This ensures that no data is collected or stored. When a user lands on a applink.dev page, a tiny snippet of JavaScript is executed in order to parse the browser's User Agent and determine the app store platform to redirect to.

With Apple allowing EU users to install alternative stores, I tried to come up with a way to allow developers to offer alternative store links based on the user's location.

This was a tricky problem to solve because I didn't want to contact a third party API to transmit the user's IP address, nor do I wanted to activate the browser's location services.

After some experimentation, I discovered that the browser Internalization API offers sufficient information to deduce if the user is based in an EU country based on their locale and timezone information. So the snippet to detect the user's current, localized timezone looks like this:

Intl.DateTimeFormat().resolvedOptions().timeZone

The value provided by the browser is then compared to a list of zones known to belong to a EU country e.g. `Europe/Brussels` or `Europe/Sofia`.

The most interesting part was coming up with a way to define the possible targets for redirection.

On one hand, I needed a way to express rules based on the user's platform and based on the user's location (e.g. is the user based within the European Union or not). The approach also needed to be extensible, as I'm planning to add support for redirects based on language and other parameters. I also didn't want to create my custom ontology as this would require some effort to create and provide shape files for validation.

JSON-LD comes to the rescue. Specifically, I decided to express the redirect targets as a β€œpossible action” for a SoftwareApplication within a CreativeWorkSeries. You can find more detailed examples in the repository, but an applink target looks something like this:

{
  "@context": "http://schema.org",
  "@type": "CreativeWorkSeries",
  "hasPart": [
    {
      "@type": "SoftwareApplication",
      "provider": {
        "@type": "Organization",
        "name": "Apple"
      },
      "potentialAction": {
        "@type": "ViewAction",
        "target": {
          "@type": "EntryPoint",
          "urlTemplate": "https://apps.apple.com/app/id12345"
        }
      }
    }
  ]
}

This is covered in great detail in the Usage section in the readme but the TL;DR; is that there are two ways to creat an applink.

If you don't require a lot of flexibility, you can construct a URL by passing the app ID for each of the 3 stores:

https://applink.dev/?apple=6444602274&google=org.joinmastodon.android&ms=9ncbcszsjrsb

Creating an advanced link requires two steps.

First, create an applink configuration file and upload it somewhere your visitors will be able to access directly. (applink.dev will initiate a fetch, so you may need to adjust the CORS configuration of your website)

Second, definte an applink URL pointing to the location of the configuration file:

https://applink.dev/?t=https://example.com/applink

That's it! If you have thoughts or ideas on how to improve applink, you're more than welcome to start a discussion by opening a GitHub issue. Thanks 🀩!

Applink can currently distinguish between an Apple device, an Android device and a Windows device. In the documentation these are referred as platforms. Support for more specific OS/platform detection is in the works.

Applink targets do not restrict the destination store used for each platform. For example, when an Apple device is detected, you can redirect the user to the AltStore, or the F-Store for a Google device. Simple links only support the Apple App Store, Google Play and the official Microsoft Stores.

The hosted applink.dev executes a tiny snippet of JavaScript on the client side in order to work. It currently supports all major browsers like Firefox >=78, Safari >=14, etc,. You can see a complete list here.

applink.dev

Tags