[{"data":1,"prerenderedAt":22},["ShallowReactive",2],{"articolo-deep-linking-in-flutter-gestire-link-universali-e-app-links":3,"comments-article-deep-linking-in-flutter-gestire-link-universali-e-app-links":21},{"id":4,"title":5,"slug":6,"excerpt":7,"body":8,"cover_image":9,"video_url":10,"status":11,"published_at":12,"meta_title":13,"meta_description":14,"category":15,"author":19},23,"Deep linking in Flutter: gestire link universali e app links","deep-linking-in-flutter-gestire-link-universali-e-app-links","Scopri come implementare il deep linking in Flutter per aprire schermate specifiche da link esterni, configurando Universal Links su iOS e App Links su Android con app_links e go_router.","## Cos'è il deep linking\n\nIl deep linking permette di aprire una schermata specifica della tua app a partire da un link esterno: un'email, un messaggio, un sito web o una notifica. Invece di portare l'utente sulla home, lo si conduce direttamente al contenuto desiderato, ad esempio una pagina prodotto (`https:\u002F\u002Fmiosito.it\u002Fprodotti\u002F42`).\n\nEsistono diverse tipologie di link che Flutter può intercettare:\n\n- **Custom URL scheme**: link del tipo `miapp:\u002F\u002Fprodotti\u002F42`. Semplici da configurare ma poco sicuri e con UX limitata.\n- **Universal Links (iOS)** e **App Links (Android)**: usano URL `https` reali e verificati. Sono lo standard consigliato perché aprono l'app se installata, altrimenti il browser.\n\nIn questa guida vediamo come gestire entrambi con il pacchetto [`app_links`](https:\u002F\u002Fpub.dev\u002Fpackages\u002Fapp_links) integrato con `go_router`.\n\n## Installazione\n\nAggiungi le dipendenze al `pubspec.yaml`:\n\n```yaml\ndependencies:\n  app_links: ^6.3.0\n  go_router: ^14.0.0\n```\n\n## Configurazione Android (App Links)\n\nNel file `android\u002Fapp\u002Fsrc\u002Fmain\u002FAndroidManifest.xml`, all'interno dell'`\u003Cactivity>` principale, aggiungi un intent filter:\n\n```xml\n\u003Cintent-filter android:autoVerify=\"true\">\n    \u003Caction android:name=\"android.intent.action.VIEW\" \u002F>\n    \u003Ccategory android:name=\"android.intent.category.DEFAULT\" \u002F>\n    \u003Ccategory android:name=\"android.intent.category.BROWSABLE\" \u002F>\n    \u003Cdata\n        android:scheme=\"https\"\n        android:host=\"miosito.it\" \u002F>\n\u003C\u002Fintent-filter>\n```\n\nL'attributo `android:autoVerify=\"true\"` richiede di pubblicare un file `assetlinks.json` su `https:\u002F\u002Fmiosito.it\u002F.well-known\u002Fassetlinks.json`:\n\n```json\n[{\n  \"relation\": [\"delegate_permission\u002Fcommon.handle_all_urls\"],\n  \"target\": {\n    \"namespace\": \"android_app\",\n    \"package_name\": \"it.miosito.miapp\",\n    \"sha256_cert_fingerprints\": [\"FA:C6:17:...\"]\n  }\n}]\n```\n\nIl fingerprint SHA-256 si ottiene dalla chiave di firma con `keytool` o dalla Google Play Console.\n\n## Configurazione iOS (Universal Links)\n\nIn Xcode, sotto **Signing & Capabilities**, aggiungi la capability **Associated Domains** e inserisci:\n\n```\napplinks:miosito.it\n```\n\nSul server pubblica `https:\u002F\u002Fmiosito.it\u002F.well-known\u002Fapple-app-site-association` (senza estensione, con `Content-Type: application\u002Fjson`):\n\n```json\n{\n  \"applinks\": {\n    \"apps\": [],\n    \"details\": [{\n      \"appID\": \"TEAMID.it.miosito.miapp\",\n      \"paths\": [\"\u002Fprodotti\u002F*\"]\n    }]\n  }\n}\n```\n\n## Intercettare i link nel codice\n\nIl pacchetto `app_links` gestisce due scenari: l'app aperta da chiusa (cold start) e l'app già in esecuzione in background.\n\n```dart\nimport 'package:app_links\u002Fapp_links.dart';\nimport 'package:flutter\u002Fmaterial.dart';\n\nclass DeepLinkHandler {\n  final AppLinks _appLinks = AppLinks();\n  final GoRouter router;\n\n  DeepLinkHandler(this.router);\n\n  Future\u003Cvoid> init() async {\n    \u002F\u002F Link che ha avviato l'app da chiusa\n    final initialUri = await _appLinks.getInitialLink();\n    if (initialUri != null) {\n      _handleUri(initialUri);\n    }\n\n    \u002F\u002F Link ricevuti mentre l'app è attiva\n    _appLinks.uriLinkStream.listen((uri) {\n      _handleUri(uri);\n    });\n  }\n\n  void _handleUri(Uri uri) {\n    \u002F\u002F Es: https:\u002F\u002Fmiosito.it\u002Fprodotti\u002F42 -> \u002Fprodotti\u002F42\n    router.go(uri.path);\n  }\n}\n```\n\n## Integrazione con go_router\n\nDefinisci le rotte che corrispondono ai path dei tuoi link:\n\n```dart\nfinal router = GoRouter(\n  routes: [\n    GoRoute(\n      path: '\u002F',\n      builder: (context, state) => const HomeScreen(),\n    ),\n    GoRoute(\n      path: '\u002Fprodotti\u002F:id',\n      builder: (context, state) {\n        final id = state.pathParameters['id']!;\n        return ProdottoScreen(id: id);\n      },\n    ),\n  ],\n);\n```\n\nInizializza l'handler dopo aver creato il router:\n\n```dart\nvoid main() async {\n  WidgetsFlutterBinding.ensureInitialized();\n  final handler = DeepLinkHandler(router);\n  await handler.init();\n  runApp(MyApp(router: router));\n}\n```\n\n> **Nota**: go_router include un supporto nativo al deep linking tramite il sistema di routing della piattaforma. Tuttavia, usare `app_links` esplicitamente dà maggiore controllo, soprattutto quando serve gestire la logica prima della navigazione (es. autenticazione o tracciamento).\n\n## Testare i deep link\n\nDurante lo sviluppo puoi simulare un link senza configurare il server.\n\nSu **Android**:\n\n```bash\nadb shell am start -a android.intent.action.VIEW \\\n  -d \"https:\u002F\u002Fmiosito.it\u002Fprodotti\u002F42\" it.miosito.miapp\n```\n\nSu **iOS** (simulatore):\n\n```bash\nxcrun simctl openurl booted \"https:\u002F\u002Fmiosito.it\u002Fprodotti\u002F42\"\n```\n\n## Best practice\n\n- **Valida sempre i parametri** ricevuti dai link: un utente potrebbe manipolare l'URL.\n- **Gestisci i fallback**: se il contenuto non esiste, mostra una schermata di errore invece di crashare.\n- **Proteggi le rotte sensibili** con controlli di autenticazione tramite il `redirect` di go_router.\n- **Verifica i file di associazione**: usa lo strumento [Statement List Tester di Google](https:\u002F\u002Fdevelopers.google.com\u002Fdigital-asset-links\u002Ftools\u002Fgenerator) per Android e i tool Apple per iOS.\n\n## Conclusione\n\nIl deep linking trasforma l'esperienza utente, collegando il mondo web alla tua app in modo fluido. Combinando `app_links` per intercettare gli URL e `go_router` per la navigazione dichiarativa, ottieni una soluzione robusta e mantenibile. La parte più delicata resta la corretta configurazione dei file di verifica lato server: una volta superato quello scoglio, i tuoi Universal Links e App Links funzioneranno in modo trasparente su entrambe le piattaforme.","https:\u002F\u002Fflutter.it\u002Fstorage\u002Farticles\u002F4dd0ab58-d8a6-432e-a0d0-7d3196d6abf5.jpg",null,"published","2026-06-27T04:00:37+00:00","Deep linking in Flutter: App Links e Universal Links","Guida pratica al deep linking in Flutter: configura App Links su Android e Universal Links su iOS con app_links e go_router per aprire schermate specifiche.",{"id":16,"name":17,"slug":18},1,"Guide","guide",{"id":16,"name":20},"Flutter Bot",[],1785219604445]