{"id":1264,"date":"2026-05-30T17:00:00","date_gmt":"2026-05-30T22:00:00","guid":{"rendered":"https:\/\/tolinku.com\/blog\/?p=1264"},"modified":"2026-03-07T04:45:44","modified_gmt":"2026-03-07T09:45:44","slug":"chrome-intent-urls","status":"publish","type":"post","link":"https:\/\/tolinku.com\/blog\/chrome-intent-urls\/","title":{"rendered":"Chrome intent:\/\/ URLs for Android Deep Linking"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Chrome on Android supports a special URL scheme, <code>intent:\/\/<\/code>, that lets web pages launch Android apps directly. Unlike custom URL schemes (which show an error if the app isn&#39;t installed) and unlike App Links (which require domain verification), intent URLs give you explicit control over what happens: which app to target, what data to pass, and where to send the user if the app isn&#39;t installed.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Intent URLs are the most powerful deep linking mechanism available from web pages on Android, but they&#39;re also the most complex. This guide covers the syntax, common patterns, fallback behavior, and when to use intent URLs vs. the alternatives.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For the App Links approach, see the <a href=\"https:\/\/tolinku.com\/blog\/android-app-links-complete-guide\/\">Android App Links complete guide<\/a>. For how Custom Tabs interact with deep links, see the <a href=\"https:\/\/tolinku.com\/blog\/chrome-custom-tabs-app-links\/\">Chrome Custom Tabs guide<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">The Intent URL Syntax<\/h2>\n\n\n\n<pre><code>intent:\/\/\n    HOST\/PATH\n    #Intent;\n        scheme=SCHEME;\n        package=PACKAGE_NAME;\n        action=ACTION;\n        category=CATEGORY;\n        S.key=value;\n        S.anotherKey=anotherValue;\n        S.browser_fallback_url=ENCODED_URL;\n    end\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">A real example:<\/p>\n\n\n\n<pre><code>intent:\/\/product\/abc123#Intent;scheme=https;package=com.example.app;S.browser_fallback_url=https%3A%2F%2Fexample.com%2Fproduct%2Fabc123;end\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This tells Chrome:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Try to open <code>https:\/\/product\/abc123<\/code> in the app <code>com.example.app<\/code>.<\/li>\n<li>If the app isn&#39;t installed, redirect to <code>https:\/\/example.com\/product\/abc123<\/code>.<\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\">Syntax Breakdown<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table>\n<thead>\n<tr>\n<th>Component<\/th>\n<th>Required<\/th>\n<th>Description<\/th>\n<\/tr>\n<\/thead>\n<tbody><tr>\n<td><code>intent:\/\/HOST\/PATH<\/code><\/td>\n<td>Yes<\/td>\n<td>The data URI (host and path)<\/td>\n<\/tr>\n<tr>\n<td><code>scheme=<\/code><\/td>\n<td>Yes<\/td>\n<td>The URI scheme (usually <code>https<\/code>)<\/td>\n<\/tr>\n<tr>\n<td><code>package=<\/code><\/td>\n<td>No<\/td>\n<td>Target app&#39;s package name. Without this, any matching app can handle the intent.<\/td>\n<\/tr>\n<tr>\n<td><code>action=<\/code><\/td>\n<td>No<\/td>\n<td>The intent action (default: <code>android.intent.action.VIEW<\/code>)<\/td>\n<\/tr>\n<tr>\n<td><code>category=<\/code><\/td>\n<td>No<\/td>\n<td>Additional category (default: <code>android.intent.category.BROWSABLE<\/code>)<\/td>\n<\/tr>\n<tr>\n<td><code>S.key=value<\/code><\/td>\n<td>No<\/td>\n<td>String extras to pass to the app<\/td>\n<\/tr>\n<tr>\n<td><code>S.browser_fallback_url=<\/code><\/td>\n<td>No<\/td>\n<td>Where to go if the app isn&#39;t installed<\/td>\n<\/tr>\n<\/tbody><\/table><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">String Extras<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Pass arbitrary data to the app using <code>S.<\/code> prefixed key-value pairs:<\/p>\n\n\n\n<pre><code>intent:\/\/open#Intent;\n  scheme=myapp;\n  package=com.example.app;\n  S.referral_code=ABC123;\n  S.campaign=summer_sale;\n  S.source=email;\n  S.browser_fallback_url=https%3A%2F%2Fexample.com;\nend\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The app receives these as string extras in the launching intent:<\/p>\n\n\n\n<pre><code class=\"language-kotlin\">override fun onCreate(savedInstanceState: Bundle?) {\n    super.onCreate(savedInstanceState)\n\n    val referralCode = intent.getStringExtra(&quot;referral_code&quot;) \/\/ &quot;ABC123&quot;\n    val campaign = intent.getStringExtra(&quot;campaign&quot;) \/\/ &quot;summer_sale&quot;\n    val source = intent.getStringExtra(&quot;source&quot;) \/\/ &quot;email&quot;\n}\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Fallback Behavior<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">With <code>S.browser_fallback_url<\/code><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">If the target app isn&#39;t installed (or the <code>package<\/code> doesn&#39;t match any installed app), Chrome navigates to the fallback URL. This is the most important parameter for a good user experience. For a detailed look at how different platforms handle missing-app scenarios, see <a href=\"https:\/\/tolinku.com\/blog\/deep-link-fallback-behavior\/\">Deep Link Fallback Behavior Across Platforms<\/a>.<\/p>\n\n\n\n<pre><code>intent:\/\/open#Intent;\n  scheme=myapp;\n  package=com.example.app;\n  S.browser_fallback_url=https%3A%2F%2Fplay.google.com%2Fstore%2Fapps%2Fdetails%3Fid%3Dcom.example.app;\nend\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The fallback URL must be URL-encoded. Common fallback targets:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Google Play Store listing (for install)<\/li>\n<li>A web version of the content<\/li>\n<li>A landing page explaining the app<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Without <code>S.browser_fallback_url<\/code><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">If no fallback is specified and the app isn&#39;t installed, Chrome navigates to the Google Play Store page for the <code>package<\/code> name. If the <code>package<\/code> parameter is also missing, Chrome does nothing (the link silently fails).<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Without <code>package<\/code><\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">If you omit <code>package<\/code>, Chrome resolves the intent using the standard Android intent resolution mechanism. Any app that matches the scheme, host, and path can handle it. This is less predictable but useful when you don&#39;t want to target a specific app.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Common Patterns<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Pattern 1: Open App or Go to Play Store<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The most common use case: try to open the app, fall back to the Play Store if not installed.<\/p>\n\n\n\n<pre><code class=\"language-html\">&lt;a href=&quot;intent:\/\/open#Intent;scheme=https;package=com.example.app;S.browser_fallback_url=https%3A%2F%2Fplay.google.com%2Fstore%2Fapps%2Fdetails%3Fid%3Dcom.example.app;end&quot;&gt;\n  Open in App\n&lt;\/a&gt;\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Pattern 2: Deep Link to Specific Content<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Open a specific screen in the app, fall back to the web version of that content.<\/p>\n\n\n\n<pre><code class=\"language-html\">&lt;a href=&quot;intent:\/\/products\/abc123#Intent;scheme=https;package=com.example.app;S.browser_fallback_url=https%3A%2F%2Fexample.com%2Fproducts%2Fabc123;end&quot;&gt;\n  View Product\n&lt;\/a&gt;\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Pattern 3: Pass Campaign Data<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Include UTM-style parameters for analytics.<\/p>\n\n\n\n<pre><code class=\"language-html\">&lt;a href=&quot;intent:\/\/open#Intent;scheme=myapp;package=com.example.app;S.utm_source=email;S.utm_medium=newsletter;S.utm_campaign=spring2026;S.browser_fallback_url=https%3A%2F%2Fexample.com%3Futm_source%3Demail;end&quot;&gt;\n  Open App\n&lt;\/a&gt;\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Pattern 4: JavaScript Generation<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Generate intent URLs dynamically:<\/p>\n\n\n\n<pre><code class=\"language-javascript\">function buildIntentUrl(options) {\n  const {\n    host = &#39;open&#39;,\n    path = &#39;&#39;,\n    scheme = &#39;https&#39;,\n    packageName,\n    extras = {},\n    fallbackUrl,\n  } = options;\n\n  let intentUrl = `intent:\/\/${host}${path}#Intent;scheme=${scheme};`;\n\n  if (packageName) {\n    intentUrl += `package=${packageName};`;\n  }\n\n  for (const [key, value] of Object.entries(extras)) {\n    intentUrl += `S.${key}=${encodeURIComponent(value)};`;\n  }\n\n  if (fallbackUrl) {\n    intentUrl += `S.browser_fallback_url=${encodeURIComponent(fallbackUrl)};`;\n  }\n\n  intentUrl += &#39;end&#39;;\n  return intentUrl;\n}\n\n\/\/ Usage\nconst url = buildIntentUrl({\n  host: &#39;products&#39;,\n  path: &#39;\/abc123&#39;,\n  packageName: &#39;com.example.app&#39;,\n  extras: { referral_code: &#39;XYZ&#39;, campaign: &#39;email&#39; },\n  fallbackUrl: &#39;https:\/\/example.com\/products\/abc123&#39;,\n});\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Intent URLs vs. App Links vs. Custom Schemes<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table>\n<thead>\n<tr>\n<th>Feature<\/th>\n<th>Intent URLs<\/th>\n<th>App Links<\/th>\n<th>Custom Schemes<\/th>\n<\/tr>\n<\/thead>\n<tbody><tr>\n<td>Works from web<\/td>\n<td>Yes (Chrome only)<\/td>\n<td>Yes (all browsers)<\/td>\n<td>Limited<\/td>\n<\/tr>\n<tr>\n<td>Fallback support<\/td>\n<td>Built-in (<code>browser_fallback_url<\/code>)<\/td>\n<td>Requires server-side redirect<\/td>\n<td>No built-in fallback<\/td>\n<\/tr>\n<tr>\n<td>Disambiguation dialog<\/td>\n<td>No (targets specific package)<\/td>\n<td>No (if verified)<\/td>\n<td>Yes (if multiple apps register)<\/td>\n<\/tr>\n<tr>\n<td>Cross-browser<\/td>\n<td>Chrome and some Chromium browsers<\/td>\n<td>All browsers<\/td>\n<td>Varies<\/td>\n<\/tr>\n<tr>\n<td>Domain verification<\/td>\n<td>Not required<\/td>\n<td>Required (Digital Asset Links)<\/td>\n<td>Not applicable<\/td>\n<\/tr>\n<tr>\n<td>Data passing<\/td>\n<td>String extras<\/td>\n<td>URL path\/query parameters<\/td>\n<td>URL path\/query parameters<\/td>\n<\/tr>\n<tr>\n<td>iOS support<\/td>\n<td>No<\/td>\n<td>No (use Universal Links)<\/td>\n<td>Partial<\/td>\n<\/tr>\n<\/tbody><\/table><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">When to Use Intent URLs<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>You need to target a specific app by package name<\/strong> and don&#39;t want the disambiguation dialog.<\/li>\n<li><strong>You need to pass structured data<\/strong> (string extras) beyond what URL parameters support.<\/li>\n<li><strong>You need a guaranteed fallback<\/strong> when the app isn&#39;t installed.<\/li>\n<li><strong>You&#39;re building Android-only web-to-app flows<\/strong> where cross-platform isn&#39;t needed.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">When to Use App Links Instead<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Cross-browser support<\/strong> is needed (intent URLs only work in Chrome).<\/li>\n<li><strong>Cross-platform<\/strong> (iOS + Android) is needed.<\/li>\n<li><strong>SEO matters<\/strong> (App Links use real HTTPS URLs that search engines can index).<\/li>\n<li><strong>You control the domain<\/strong> and can host the Digital Asset Links file.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">When Tolinku Links Are Better<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/tolinku.com\/features\/deep-linking\">Tolinku deep links<\/a> abstract away the platform differences. A single Tolinku URL works on iOS (Universal Links), Android (App Links), and web (redirect fallback), without needing to generate platform-specific intent URLs. The platform handles browser detection, app-installed detection, and fallback routing.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Use intent URLs only when you need the specific capabilities they offer (package targeting, string extras) and you&#39;re building an Android-only flow.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Security Considerations<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Validate Incoming Intent Data<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Any app that receives intents from intent URLs should validate the data. For the full intent filter configuration that determines which URLs your app handles, see <a href=\"https:\/\/tolinku.com\/blog\/android-intent-filters-deep-links\/\">Android Intent Filters for Deep Links<\/a>.<\/p>\n\n\n\n<pre><code class=\"language-kotlin\">override fun onCreate(savedInstanceState: Bundle?) {\n    super.onCreate(savedInstanceState)\n\n    val uri = intent.data ?: return\n    val referralCode = intent.getStringExtra(&quot;referral_code&quot;)\n\n    \/\/ Validate: referral codes should be alphanumeric, max 20 chars\n    if (referralCode != null &amp;&amp; !referralCode.matches(Regex(&quot;^[a-zA-Z0-9]{1,20}$&quot;))) {\n        Log.w(&quot;DeepLink&quot;, &quot;Invalid referral code: $referralCode&quot;)\n        return\n    }\n\n    \/\/ Safe to use referralCode\n}\n<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Don&#39;t Trust the <code>package<\/code> Parameter<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The <code>package<\/code> parameter in an intent URL tells Chrome which app to launch, but the receiving app shouldn&#39;t assume it was launched from a trusted source. Always validate incoming data as if it came from an untrusted external source.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Avoid Sensitive Data in Intent URLs<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Intent URLs are visible in browser history, server logs, and potentially to intermediary services. Don&#39;t include sensitive data (tokens, passwords, PII) directly in the URL. Instead, pass a short-lived reference ID and resolve the sensitive data server-side.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For setting up App Links with <a href=\"https:\/\/tolinku.com\/docs\/developer\/app-links\/\">Tolinku<\/a>, the platform generates correctly formatted deep links that work across all Android browsers and versions, not just Chrome.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Use Chrome intent:\/\/ URLs to deep link into Android apps from web pages. Learn the syntax, fallback behavior, package targeting, and when to use intent URLs vs App Links.<\/p>\n","protected":false},"author":2,"featured_media":1263,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"rank_math_title":"Chrome intent:\/\/ URLs for Android Deep Linking","rank_math_description":"Use Chrome intent:\/\/ URLs to deep link into Android apps. Learn the syntax, fallback behavior, and when to use intent URLs vs App Links.","rank_math_focus_keyword":"chrome intent URLs","rank_math_canonical_url":"","rank_math_facebook_title":"","rank_math_facebook_description":"","rank_math_facebook_image":"https:\/\/tolinku.com\/blog\/wp-content\/uploads\/2026\/03\/og-chrome-intent-urls.png","rank_math_facebook_image_id":"","rank_math_twitter_title":"","rank_math_twitter_description":"","rank_math_twitter_image":"https:\/\/tolinku.com\/blog\/wp-content\/uploads\/2026\/03\/og-chrome-intent-urls.png","footnotes":""},"categories":[10],"tags":[25,23,314,20,323,69,41],"class_list":["post-1264","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-android","tag-android","tag-app-links","tag-chrome","tag-deep-linking","tag-intent-urls","tag-mobile-development","tag-web-to-app"],"_links":{"self":[{"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/posts\/1264","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/comments?post=1264"}],"version-history":[{"count":4,"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/posts\/1264\/revisions"}],"predecessor-version":[{"id":2813,"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/posts\/1264\/revisions\/2813"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/media\/1263"}],"wp:attachment":[{"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/media?parent=1264"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/categories?post=1264"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/tolinku.com\/blog\/wp-json\/wp\/v2\/tags?post=1264"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}