$npx -y skills add mmiani/kotlin-kmp-claude-agent-skills --skill kotlin-platform-app-links-and-deep-linksUse when designing, implementing, or reviewing Android deep links, web links, and App Links in KMP projects — intent-filter design, host verification, manifest scope, and assetlinks.json configuration.
| 1 | # Android App Links and Deep Links |
| 2 | |
| 3 | Use this skill when designing, implementing, or reviewing deep-linking behavior in a Kotlin Multiplatform project with Android support. |
| 4 | |
| 5 | This skill is intentionally strict. Its purpose is to keep Android deep links, web links, and App Links structurally correct, verified where appropriate, compatible with realistic navigation behavior, and separated cleanly from shared route interpretation logic. |
| 6 | |
| 7 | ## Primary goals |
| 8 | |
| 9 | The deep-linking design should optimize for: |
| 10 | |
| 11 | - clear distinction between deep links, web links, and verified App Links |
| 12 | - manifest declarations that match intended URL ownership |
| 13 | - host verification that is reliable and maintainable |
| 14 | - realistic navigation and back-stack behavior after external entry |
| 15 | - separation between Android registration/verification and shared route handling |
| 16 | - minimal ambiguity about which URLs should open the app |
| 17 | - support for server-side refinement where Dynamic App Links are used |
| 18 | |
| 19 | Do not treat all incoming URLs as equivalent. |
| 20 | Treat verified App Links as a distinct architectural surface. |
| 21 | |
| 22 | --- |
| 23 | |
| 24 | ## Official defaults to prefer |
| 25 | |
| 26 | Unless the project has a strong reason not to, prefer: |
| 27 | |
| 28 | - Android App Links for owned HTTPS web domains |
| 29 | - custom URI schemes only when web-link verification is not the right tool |
| 30 | - explicit intent filters with `VIEW`, `DEFAULT`, and `BROWSABLE` |
| 31 | - separate intent filters for unique URL combinations instead of relying on merged `<data>` semantics |
| 32 | - broad manifest host scope with finer path-level refinement in `assetlinks.json` when using Dynamic App Links on Android 15+ |
| 33 | - Android registration and verification in platform code |
| 34 | - shared route interpretation in shared/navigation code |
| 35 | |
| 36 | --- |
| 37 | |
| 38 | ## Link-type distinctions |
| 39 | |
| 40 | ### 1. Custom deep links |
| 41 | Examples: |
| 42 | - `myapp://product/123` |
| 43 | |
| 44 | Use when: |
| 45 | - links come from controlled sources |
| 46 | - you need non-web routing |
| 47 | - website ownership/verification is not the main requirement |
| 48 | |
| 49 | Risks: |
| 50 | - not standard web links |
| 51 | - can still trigger chooser/disambiguation issues if other apps claim the same custom scheme |
| 52 | |
| 53 | ### 2. Web links |
| 54 | Examples: |
| 55 | - `https://example.com/product/123` |
| 56 | |
| 57 | These are standard web URLs. Without App Link verification, Android may still show disambiguation or route to the browser depending on app/user/system state. |
| 58 | |
| 59 | ### 3. Android App Links |
| 60 | These are verified HTTP(S) web links associated with your website. They provide the strongest user-trust and ownership model for opening app content from your web domains. |
| 61 | |
| 62 | Review expectation: |
| 63 | - use App Links for domains the app genuinely owns and wants to claim as app entry points |
| 64 | |
| 65 | --- |
| 66 | |
| 67 | ## Review dimensions |
| 68 | |
| 69 | ### 1. URL ownership and link-type choice |
| 70 | |
| 71 | Check whether the proposal uses the right link type for the job. |
| 72 | |
| 73 | Prefer: |
| 74 | - App Links for owned website domains |
| 75 | - web URLs where website fallback matters |
| 76 | - custom schemes only when they are truly appropriate |
| 77 | |
| 78 | Flag as a concern when: |
| 79 | - custom schemes are used where verified HTTPS ownership would be better |
| 80 | - App Links are declared for domains the team does not fully control |
| 81 | - multiple unrelated link types are mixed with no clear reason |
| 82 | |
| 83 | ### 2. Intent-filter correctness |
| 84 | |
| 85 | For Android deep links and App Links, review whether the manifest filters are structurally correct. |
| 86 | |
| 87 | Expected pieces: |
| 88 | - `android.intent.action.VIEW` |
| 89 | - `android.intent.category.DEFAULT` |
| 90 | - `android.intent.category.BROWSABLE` |
| 91 | |
| 92 | Check whether: |
| 93 | - filters declare the intended scheme, host, and optional path scope |
| 94 | - filters are as clear as possible |
| 95 | - each filter corresponds to a coherent URL family |
| 96 | |
| 97 | Important review rule: |
| 98 | - do not casually combine unrelated `<data>` elements in one filter, because Android merges them and may create unintended URL combinations |
| 99 | |
| 100 | Flag as a concern when: |
| 101 | - categories or action are incomplete |
| 102 | - one filter accidentally matches more URLs than intended |
| 103 | - path scoping is implicit and hard to reason about |
| 104 | - filter merging creates accidental combinations |
| 105 | |
| 106 | ### 3. App Link verification model |
| 107 | |
| 108 | Review whether host verification is designed correctly. |
| 109 | |
| 110 | Check whether: |
| 111 | - host verification is expected and supported for every declared App Link host |
| 112 | - the team understands that verification behavior differs by Android version |
| 113 | - multi-host declarations are intentional |
| 114 | |
| 115 | Important platform behavior: |
| 116 | - on Android 12+, if multiple hosts are declared, the system attempts to verify each one independently, and any verified host can become the default handler for that host |
| 117 | - on Android 11 and lower, verification can fail for the whole set if one declared host cannot be verified |
| 118 | |
| 119 | Flag as a concern when: |
| 120 | - many hosts are bundled casually into one design without operational ownership |
| 121 | - verification assumptions ign |