capacitor-deep-linking

安装量: 53
排名: #13874

安装

npx skills add https://github.com/cap-go/capgo-skills --skill capacitor-deep-linking

Deep Linking in Capacitor Implement deep links, universal links, and app links in Capacitor apps. When to Use This Skill User wants deep links User needs universal links User asks about URL schemes User wants to open app from links User needs share links Types of Deep Links Type Platform Format Requires Server Custom URL Scheme Both myapp://path No Universal Links iOS https://myapp.com/path Yes App Links Android https://myapp.com/path Yes Quick Start Install Plugin bun add @capacitor/app bunx cap sync Handle Deep Links import { App } from '@capacitor/app' ; // Listen for deep link opens App . addListener ( 'appUrlOpen' , ( event ) => { console . log ( 'App opened with URL:' , event . url ) ; // Parse and navigate const url = new URL ( event . url ) ; handleDeepLink ( url ) ; } ) ; function handleDeepLink ( url : URL ) { // Custom scheme: myapp://product/123 // Universal link: https://myapp.com/product/123 const path = url . pathname || url . host + url . pathname ; // Route based on path if ( path . startsWith ( '/product/' ) ) { const productId = path . split ( '/' ) [ 2 ] ; navigateTo ( /product/ ${ productId } ) ; } else if ( path . startsWith ( '/user/' ) ) { const userId = path . split ( '/' ) [ 2 ] ; navigateTo ( /profile/ ${ userId } ) ; } else if ( path === '/login' ) { navigateTo ( '/login' ) ; } else { navigateTo ( '/' ) ; } } Custom URL Scheme iOS Configuration

< key

CFBundleURLTypes </ key

< array

< dict

< key

CFBundleURLName </ key

< string

com.yourcompany.yourapp </ string

< key

CFBundleURLSchemes </ key

< array

< string

myapp </ string

< string

myapp-dev </ string

</ array

</ dict

</ array

Android Configuration

< activity android: name = " .MainActivity "

< 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 = " myapp " /> </ intent-filter

</ activity

Test Custom Scheme

iOS Simulator

xcrun simctl openurl booted "myapp://product/123"

Android

adb shell am start -a android.intent.action.VIEW -d "myapp://product/123" Universal Links (iOS) 1. Enable Associated Domains In Xcode: Select App target Signing & Capabilities Capability > Associated Domains Add: applinks:myapp.com 2. Create apple-app-site-association Host at https://myapp.com/.well-known/apple-app-site-association : { "applinks" : { "apps" : [ ] , "details" : [ { "appID" : "TEAMID.com.yourcompany.yourapp" , "paths" : [ "/product/" , "/user/" , "/invite/" , "NOT /api/" ] } ] } } Requirements : Served over HTTPS Content-Type: application/json No redirects File at root domain 3. Info.plist

< key

com.apple.developer.associated-domains </ key

< array

< string

applinks:myapp.com </ string

< string

applinks:www.myapp.com </ string

</ array

Verify Universal Links

Validate AASA file

curl -I https://myapp.com/.well-known/apple-app-site-association

Check Apple CDN cache

curl "https://app-site-association.cdn-apple.com/a/v1/myapp.com" App Links (Android) 1. Create assetlinks.json Host at https://myapp.com/.well-known/assetlinks.json : [ { "relation" : [ "delegate_permission/common.handle_all_urls" ] , "target" : { "namespace" : "android_app" , "package_name" : "com.yourcompany.yourapp" , "sha256_cert_fingerprints" : [ "AA:BB:CC:DD:EE:FF:00:11:22:33:44:55:66:77:88:99:AA:BB:CC:DD:EE:FF:00:11:22:33:44:55:66:77:88:99" ] } } ] Get SHA256 Fingerprint

Debug keystore

keytool -list -v -keystore ~/.android/debug.keystore -alias androiddebugkey -storepass android -keypass android

Release keystore

keytool -list -v -keystore release.keystore -alias your-alias

From APK

keytool -printcert -jarfile app-release.apk 2. AndroidManifest.xml

< activity android: name = " .MainActivity "

< intent-filter android: autoVerify = " true "

< action android: name = " android.intent.action.VIEW " /> < category android: name = " android.intent.category.DEFAULT " /> < category android: name = " android.intent.category.BROWSABLE " /> < data android: scheme = " https " /> < data android: host = " myapp.com " /> < data android: pathPrefix = " /product " /> < data android: pathPrefix = " /user " /> < data android: pathPrefix = " /invite " /> </ intent-filter

</ activity

Verify App Links

Validate assetlinks.json

curl https://myapp.com/.well-known/assetlinks.json

Use Google's validator

https://developers.google.com/digital-asset-links/tools/generator

Check link handling on device

adb shell pm get-app-links com.yourcompany.yourapp Advanced Routing React Router Integration import { App } from '@capacitor/app' ; import { useHistory } from 'react-router-dom' ; import { useEffect } from 'react' ; function DeepLinkHandler ( ) { const history = useHistory ( ) ; useEffect ( ( ) => { App . addListener ( 'appUrlOpen' , ( event ) => { const url = new URL ( event . url ) ; const path = getPathFromUrl ( url ) ; // Navigate using React Router history . push ( path ) ; } ) ; // Check if app was opened with URL App . getLaunchUrl ( ) . then ( ( result ) => { if ( result ?. url ) { const url = new URL ( result . url ) ; const path = getPathFromUrl ( url ) ; history . push ( path ) ; } } ) ; } , [ ] ) ; return null ; } function getPathFromUrl ( url : URL ) : string { // Handle both custom scheme and https if ( url . protocol === 'myapp:' ) { return '/' + url . host + url . pathname ; } return url . pathname + url . search ; } Vue Router Integration import { App } from '@capacitor/app' ; import { useRouter } from 'vue-router' ; import { onMounted } from 'vue' ; export function useDeepLinks ( ) { const router = useRouter ( ) ; onMounted ( async ( ) => { App . addListener ( 'appUrlOpen' , ( event ) => { const path = parseDeepLink ( event . url ) ; router . push ( path ) ; } ) ; const launchUrl = await App . getLaunchUrl ( ) ; if ( launchUrl ?. url ) { const path = parseDeepLink ( launchUrl . url ) ; router . push ( path ) ; } } ) ; } Deferred Deep Links Handle links when app wasn't installed: import { App } from '@capacitor/app' ; import { Preferences } from '@capacitor/preferences' ; // On first launch, check for deferred link async function checkDeferredDeepLink ( ) { const { value : isFirstLaunch } = await Preferences . get ( { key : 'firstLaunch' } ) ; if ( isFirstLaunch !== 'false' ) { await Preferences . set ( { key : 'firstLaunch' , value : 'false' } ) ; // Check with your attribution service const deferredLink = await fetchDeferredLink ( ) ; if ( deferredLink ) { handleDeepLink ( new URL ( deferredLink ) ) ; } } } Query Parameters App . addListener ( 'appUrlOpen' , ( event ) => { const url = new URL ( event . url ) ; // Get query parameters const source = url . searchParams . get ( 'source' ) ; const campaign = url . searchParams . get ( 'campaign' ) ; const referrer = url . searchParams . get ( 'ref' ) ; // Track attribution analytics . logEvent ( 'deep_link_open' , { path : url . pathname , source , campaign , referrer , } ) ; // Navigate with state navigateTo ( url . pathname , { state : { source , campaign , referrer } , } ) ; } ) ; OAuth Callback Handling // Handle OAuth redirect App . addListener ( 'appUrlOpen' , async ( event ) => { const url = new URL ( event . url ) ; if ( url . pathname === '/oauth/callback' ) { const code = url . searchParams . get ( 'code' ) ; const state = url . searchParams . get ( 'state' ) ; const error = url . searchParams . get ( 'error' ) ; if ( error ) { handleOAuthError ( error ) ; return ; } if ( code && validateState ( state ) ) { await exchangeCodeForToken ( code ) ; navigateTo ( '/home' ) ; } } } ) ; Testing Test Matrix Scenario Command Custom scheme myapp://path Universal link cold start Tap link with app closed Universal link warm start Tap link with app in background Universal link in Safari Type URL in Safari App link cold start Tap link with app closed App link in Chrome Tap link in Chrome Debug Tools

iOS: Check associated domains entitlement

codesign -d --entitlements - App.app | grep associated-domains

iOS: Reset Universal Links cache

xcrun simctl erase all

Android: Check verified links

adb shell dumpsys package d | grep -A5 "Package: com.yourcompany.yourapp" Common Issues Issue Solution Universal Links not working Check AASA file, SSL, entitlements App Links not verified Check assetlinks.json, fingerprint Links open in browser Check intent-filter, autoVerify Cold start not handled Use App.getLaunchUrl() Simulator issues Reset simulator, rebuild app Resources Capacitor App Plugin: https://capacitorjs.com/docs/apis/app Universal Links Guide: https://developer.apple.com/documentation/xcode/supporting-universal-links-in-your-app Android App Links: https://developer.android.com/training/app-links Digital Asset Links Validator: https://developers.google.com/digital-asset-links/tools/generator

返回排行榜