Lesson 15 / 25

Passing Data and Deep Links

Arguments, query parameters and platform links.

Getting data to the next screen

Pass small, serialisable data such as IDs through the path or query string (/products/42?tab=reviews) so the screen can rebuild itself from the URL alone - this is what makes refresh on the web and deep links work. Load the full object inside the destination screen. go_router also supports an extra object, but it is not part of the URL and is lost on a web refresh or a cold-start deep link. Deep links open the app from outside: Android App Links need an intent filter and a assetlinks.json file on your domain, and iOS Universal Links need the Associated Domains entitlement and an apple-app-site-association file. With a router configured, Flutter passes the incoming path to it; check the Flutter deep linking guide for current setup steps.

Reading path and query parameters

Inside a GoRoute builder (go_router 10+ style).

GoRoute(
  path: '/products/:id',
  builder: (context, state) {
    final id = state.pathParameters['id']!;
    final tab = state.uri.queryParameters['tab'] ?? 'details';
    return ProductPage(id: id, initialTab: tab);
  },
);

// a deep link such as https://shop.example.com/products/42?tab=reviews
// opens ProductPage(id: '42', initialTab: 'reviews')

Test links from the command line

On Android you can fire a link with adb shell am start -a android.intent.action.VIEW -d ""; on the iOS simulator use xcrun simctl openurl booted "".

Quick check: Why prefer passing an ID in the URL over passing a whole object with extra?

  • The screen can be rebuilt from the URL alone, so refreshes and deep links work
  • Objects cannot be passed in Dart
  • URLs are encrypted
  • extra is slower to type
Answer

The screen can be rebuilt from the URL alone, so refreshes and deep links work — Data that is not in the URL is lost when the app is opened from a link.