Support Deep Links in your App
The first part to getting your app content in the Google index is ensuring it supports deep links to your content. This guide covers how you do that by adding intent filters and activity logic to respond to deep link intents when users click through to your app from Search results, query autocompletions, and Now on Tap.Note: Participating in App Indexing currently requires that your app has corresponding content on the web that has also been indexed by Google. If you have an app without corresponding web-page content, and you'd like it discovered by Google Search, fill out our app-only interest form.
Create intent filters
In order for deep links from Google Search results to trigger content views within your app,
your app needs intent filters to match HTTP or custom scheme URIs for its content.
Create one intent filter for each deep link format that should launch your app content. For
example, you'll need two intent filters if your app supports both http://recipe-app.com
and recipe-app:// formats.
Example intent filters
The following example demonstrates a URI pattern intended to match HTTP URIs so that the user can open your native app instead of the web page when tapping a link from Search results. Here, users enter the app using an intent to view information about recipes.
This example also shows an intent filter designed to handle custom URI schemes. If you use custom scheme URIs, you can use these data URI formats instead or in addition to HTTP URIs.
<activity
android:name="com.example.android.RecipeActivity"
android:label="@string/title_recipe" >
<intent-filter android:label="@string/filter_title_viewrecipe">
<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 "recipe-app://recipes" -->
<data android:scheme="recipe-app"
android:host="recipes" />
</intent-filter>
<intent-filter android:label="@string/filter_title_viewrecipes">
<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://recipe-app.com/recipes" -->
<data android:scheme="http"
android:host="recipe-app.com"
android:pathPrefix="/recipes" />
</intent-filter>
</activity>
The example above allows your app to respond to both HTTP URIs and custom scheme URIs such as the following:
http://recipe-app.com/recipesrecipe-app://recipes/grilled-potato-saladrecipe-app://recipes/desserts/peach-pie
Intent filters for deep links should have these elements:
| Tag | Description |
|---|---|
| <action> | Specifies the ACTION_VIEW intent action so that the intent filter can be reached from Google Search. |
| <data> | One for each URI format that the activity accepts. At
minimum, the You can add additional attributes to further refine the
type of URI that the activity accepts. For example, you might
have multiple activities that accept similar URIs, but which
differ simply based on the path name. In this case, use
the |
| <category> | Defines both BROWSABLE and DEFAULT intent activities:
|
Verify deep link syntax
Android Studio lint (version 1.3+) automatically flags deep link syntax errors for your intent filters. You can also manually run syntax checking by selecting Analyze > Inspect Code from the application or right-click menu. To turn off deep link checking, disable Missing AppIndexing Support and Wrong usage of Appindexing api from the Android lint inspections panel. See both the lint documentation for Android Studio and Configuring lint in Android.
Deep link syntax warnings appear highlighted in yellow.

Deep link errors are indicated by a red underline.

All errors appear in the bottom window of the editor, for quick access to the line in your manifest.

Add logic to handle deep link intents
Once the system starts the app activity through an intent filter, use the data provided by the
Intent to determine your app's view response. Call
the getData() and getAction() methods
to retrieve the data and action associated with the incoming
Intent. You can call these methods at any time during the
lifecycle of the activity, but you should generally do so during
early callbacks such as onCreate() or onStart().
The following example passes the incoming Intent to a helper
method onNewIntent() in onCreate().
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_recipes);
onNewIntent(getIntent());
}
Here, the onNewIntent() method
verifies the deep link format and displays the recipe content:
protected void onNewIntent(Intent intent) {
String action = intent.getAction();
String data = intent.getDataString();
if (Intent.ACTION_VIEW.equals(action) && data != null) {
String recipeId = data.substring(data.lastIndexOf("/") + 1);
Uri contentUri = RecipeContentProvider.CONTENT_URI.buildUpon()
.appendPath(recipeId).build();
showRecipe(contentUri);
}
}
Restrict access to some content (optional)
In some cases, you might not want Google to index parts of your
app. To do this, first include a noindex.xml file
in your Android app to indicate which deep links should not be
indexed. Then, reference the noindex.xml in the
application section of the app’s AndroidManifest.xml file.
Create the noindex.xml file
This file indicates a list of URIs to exclude, or a list of URI prefixes. This is similar to how the robots noindex meta tag works for websites.
Create a new XML file, res/xml/noindex.xml, and
put it in your app's XML resources directory. It should look
like the following:
<?xml version="1.0" encoding="utf-8"?> <search-engine xmlns:android="http://schemas.android.com/apk/res/android"> <noindex uri="http://recipe-app.com/recipes/hidden_uri"/> <noindex uriPrefix="http://recipe-app.com/recipes/hidden_prefix"/> <noindex uri="recipe-app://hidden_path"/> <noindex uriPrefix="recipe-app://hidden_prefix"/> </search-engine>
Google will not index those deep links that either match the uri attribute
exactly or that start with the string matching uriPrefix attribute.
Reference the noindex.xml file
After the noindex.xml file is added, reference it
in the application section of the app’s
AndroidManifest.xml file. For example:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.android.Recipes">
<application>
<activity android:name="com.example.android.RecipesActivity"
android:label="@string/title_recipes" >
<intent-filter android:label="@string/filter_title_viewrecipes">
<action android:name="android.intent.action.VIEW"/>
...
</activity>
<meta-data android:name="search-engine" android:resource="@xml/noindex"/>
</application>
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>
<meta-data android:name="search-engine" android:resource="@xml/noindex"/>
specifies where the noindex.xml file can be found in the app. In order to make sure that
your app is indexed consistently, the same
Next, publish your deep links to help Google understand and discover your app content.