1. Make Your App Deep-linkable (Android)

1.1 App manifest

An app manifest is an app's official listing of structured metadata following a preset schema. Developers should maintain their own app manifests on the open web and define deep links in the manifest. Defining deep links for an app ensures that end users can access these deep states within the app directly. Android supports a file named AndroidManifest.XML which represents the app manifest file. Developers should describe the following in their app manifest file:

Activity - Description of the entire Android app activity. This tag starts with a namespace declaration <xmlns:android= ...> and includes name and label tags that are easily readable.

Action - The action provided by the intent. For URL handling, the intent should be set to VIEW.

Category - Categories are usually set to BROWSABLE (can be safely invoked by browser) or DEFAULT (for taking default action).

Data - Specifies a set of URLs that can be handled by the app. Developers can use a scheme across all URLs that need to be handled, as well as specific URLs with a given host name, path, prefix, pattern etc.

Intent-Filter - The set of intents that need to be handled by a specified activity.

Example:

<activity xmlns:android="http://schemas.android.com/apk/res/android"
    android:name="foursquare.HandleURL"
    android:label="Foursquare">
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data android:scheme="http" android:host="foursquare.com" />
    </intent-filter>
</activity>

1.2 Handling intent

Intents allow apps to register themselves to get launched in response to actions taken by the user, such as opening a specific URL. Inside the Activity that was made deep linkable, developers can call getIntent() to retrieve the intent. Invoking intent.getAction() and intent.getData() will return the actual URL that needs to be opened to load the correct deep state.

Example:

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    Intent intent = getIntent();
    Uri data = intent.getData();
    String path = data.getPath();
    // Url "https://foursquare.com/explore?near=Mountain%20View&q=Dinner".
    // Path object is now equal to "explore?near=Mountain%20View&q=Dinner"
    // Use this path to load the correct state
}

2. Publishing Deep-links

2.1 AppURL in sitemap.xml

Sitemap is an XML file listing the URLs on a site, including additional information for each URL which allows search engines to crawl the site more intelligently. A full description of sitemap protocol is available here - http://www.sitemaps.org/protocol.html.

AppURL standard supports adding <xhtml: link rel="alternate"> tag. (just like Google App Indexing except without supporting the special semantics of "android-app://" URLs).

AppURL also adds support for a type="x-edition/your-edition-@id-here" attribute of both <loc> and <xhtml:link> which references a SoftwareProduct.editions[i].@id value.

The SoftwareProduct.editions[i].platform field values can be one of ["android", "ios", "windows", "web", "blackberry", "firefox"]

Example sitemap.xml

<?xml version="1.0" encoding="UTF-8" ?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
    xmlns:xhtml="http://www.w3.org/1999/xhtml">
  <url>
    <loc type="x-edition/desktop-web">
        http://foursquare.com/explore?q=lunch
    </loc>
    <xhtml:link rel="alternate"
      type="x-edition/mobile-web" href="http://foursquare.com/explore?q=lunch" />
    <xhtml:link rel="alternate"
      type="x-edition/android-4.0" href="http://foursquare.com/explore?q=lunch" />
    <xhtml:link rel="alternate" type="x-edition/old-winphone"
      href="http://foursquare.com/explore?q=lunch" />
    <xhtml:link rel="alternate" type="x-edition/new-winphone"
      href="http://foursquare.com/explore?q=lunch" />
  </url>
</urlset>

2.2 AppURL in HTML meta tags

Meta tags are tags specified in a HTML document which provide structured metadata information about a web page. The Meta tags are inside the <head> element and always described as key=value pairs.

AppURL includes a specification that allows XHTML <link rel="alternate"> tags to specify an editions attribute to identify which of a Software Product's Editions the given href value is the Access URL for.

Example:

<html>
<head>
        …
    <link rel="alternate" type="x-edition/android-newest" href="http://example.com/123" />
    <link rel="alternate" type="x-edition/ios" href="example:///123" />
    <link rel="alternate" type="x-edition/old-winphone" href="example:///foo/123" />
    <link rel="alternate" type="x-edition/new-winphone" href="example:///foo/123" />
        …
</head>
<body>...</body>

3. Other Standards

3.1 Google App Indexing

Developers must define intent filters in the app manifest which describe how to reach specific content inside an app. The <intent-filter> elements in the app manifest file include tags for <action>, <data> and <category>. For more information see - https://developers.google.com/app-indexing/webmasters/app

Example:

<activity
    android:name="com.example.android.GizmosActivity"
    android:label="@string/title_gizmos">
    <intent-filter android:label="@string/filter_title_viewgizmos" />
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <!-- Accepts URIs that begin with "example://gizmos" -->
        <data android:scheme="example"
            android:host="gizmos" />
    </intent-filter>
    <intent-filter android:label="@string/filter_title_viewgizmos">
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <!-- Accepts URIs that begin with "http://example.com/gizmos" -->
            <data android:scheme="http"
               android:host="example.com"
               android:pathPrefix="/gizmos" />
    </intent-filter>
</activity>

3.2 Facebook App Links

Facebook provides support for App links to existing web content by defining metadata that describes how apps link to the content inside the app. For more information see https://developers.facebook.com/docs/applinks/add-to-content. The metadata is specified in the <head> tag.

Example:

<head>
    ...
    <meta property="al:android:url" content="sharesample://story/1234" />
    <meta property="al:android:package" content="com.facebook.samples.sharesample" />
    <meta property="al:android:app_name" content="ShareSample" />
    ...
</head>

The app manifest file contains intent-filter definitions which allow the app to respond correctly to deep-links. An example Android app manifest file looks like -

<activity android:name=".MainActivity"
    android:label="@string/app_name" >
    ...
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <data android:scheme="sharesample" />
    </intent-filter>
 </activity>

3.3 Twitter App Cards

Twitter Cards enable developers to deep-link into their apps by adding metadata markup tags to any Twitter card type.

<meta name="twitter:app:country" content="US" />
<meta name="twitter:app:name:iphone" content="Example App" />
<meta name="twitter:app:id:iphone" content="306934135" />
<meta name="twitter:app:url:iphone" content="example://action/5149e249222f9e600a7540ef" />
<meta name="twitter:app:name:ipad" content="Example App" />
<meta name="twitter:app:id:ipad" content="306934135" />
<meta name="twitter:app:url:ipad" content="example://action/5149e249222f9e600a7540ef" />
<meta name="twitter:app:name:googleplay" content="Example App" />
<meta name="twitter:app:id:googleplay" content="com.example.app" />
<meta name="twitter:app:url:googleplay" content="http://example.com/action/5149e249222f9e600a7540ef" />

For Android, deep link information is passed in through <intent-filter> tags which includes specifying <action>, <category> and <data> tags. For more information, see https://dev.twitter.com/cards/mobile

<intent-filter android:label="@string/filter_title_viewcardcontent">
    <action android:name="android.intent.action.VIEW" />
    <category android:name="android.intent.category.DEFAULT" />
    <category android:name="android.intent.category.BROWSABLE" />
    <!-- Accepts URIs that begin with "example://action" -->
    <data android:scheme="example" android:host="action" />
</intent-filter>

4. Comparison of the different deep linking standards

[1] Coming soon.
[2] Only few views supported.
[3] For everybody.
[4] Only for Android
[5] For everybody.
[6] Only consumed by Twitter.

As shown in the table, all main standards today which provide a public, cross-platform standard for deep linking their apps support the same specifications. Using AppURL ensures that Developers’ apps are successfully deep linked and follow the same standards as specified by Google App Indexing, Facebook App Links and Twitter App Cards.