Flutter Setup Declarative Routing

作者 flutter0ef3972f93e2無授權條款3K 個星標收錄於 2026年10月8日更新於 2026年10月8日儲存庫2 天前更新

Configure `MaterialApp.router` using a package like `go_router` for advanced URL-based navigation. Use when developing web applications or mobile apps that require specific deep linking and browser history support.

AI 產生的概覽

指導 Flutter 開發者使用 go_router 設定宣告式路由與深層連結。

功能
此技能提供在 Flutter 應用程式中使用 go_router 套件設定宣告式路由的逐步說明。內容涵蓋初始化 GoRouter 執行個體、將其綁定至 MaterialApp.router、為 Android 與 iOS 設定平台深層連結,以及使用 StatefulShellRoute 實作巢狀導覽。它會產出設定程式碼、平台資訊清單與權限片段,以及驗證指令。
適用情境
適用於建置需要以 URL 為基礎的導覽、深層連結、瀏覽器歷史記錄支援或常駐底部導覽外殼的 Flutter 網頁或行動應用程式。適合在全新或既有 Flutter 專案中建置路由基礎架構的開發者。
執行需求
需要 Flutter 開發環境,以及 go_router 套件和 flutter_web_plugins。平台深層連結設定需要 Android 與 iOS 專案檔案、用於託管 assetlinks.json 和 apple-app-site-association 的網域,以及 ADB 和 xcrun 等測試工具。不包含指令碼,僅為說明文件。

Implementing Routing and Deep Linking

Contents

Core Concepts

Use the go_router package for declarative routing in Flutter. It provides a robust API for complex routing scenarios, deep linking, and nested navigation.

  • GoRouter: The central configuration object defining the application's route tree.
  • GoRoute: A standard route mapping a URL path to a Flutter screen.
  • ShellRoute / StatefulShellRoute: Wraps child routes in a persistent UI shell (e.g., a BottomNavigationBar). StatefulShellRoute maintains the state of parallel navigation branches.
  • Path URL Strategy: Removes the default # fragment from web URLs, essential for clean deep linking across platforms.

Workflow: Initializing the Application and Router

Follow this workflow to bootstrap a new Flutter application with go_router and configure the root routing mechanism.

Task Progress

  • Create the Flutter application.
  • Add the go_router dependency.
  • Configure the URL strategy for web/deep linking.
  • Implement the GoRouter configuration.
  • Bind the router to MaterialApp.router.

1. Scaffold the Application

Run the following commands to create the app and add the required routing package:

bash
flutter create <app-name>cd <app-name>flutter pub add go_router

2. Configure the Router

Define a top-level GoRouter instance. Handle authentication or state-based routing using the redirect parameter.

dart
import 'package:flutter/material.dart';import 'package:go_router/go_router.dart';import 'package:flutter_web_plugins/url_strategy.dart';
void main() {  // Use path URL strategy to remove the '#' from web URLs  usePathUrlStrategy();  runApp(const MyApp());}
final GoRouter _router = GoRouter(  initialLocation: '/',  routes: [    GoRoute(      path: '/',      builder: (context, state) => const HomeScreen(),      routes: [        GoRoute(          path: 'details/:id',          builder: (context, state) => DetailsScreen(id: state.pathParameters['id']!),        ),      ],    ),  ],  errorBuilder: (context, state) => ErrorScreen(error: state.error),);
class MyApp extends StatelessWidget {  const MyApp({super.key});
  @override  Widget build(BuildContext context) {    return MaterialApp.router(      routerConfig: _router,      title: 'Routing App',    );  }}

Workflow: Configuring Platform Deep Linking

Configure the native platforms to intercept specific URLs and route them into the Flutter application.

Task Progress

  • Determine target platforms (iOS, Android, or both).
  • Apply conditional configuration for Android (Manifest + Asset Links).
  • Apply conditional configuration for iOS (Plist + Entitlements + AASA).
  • Run validator -> review errors -> fix.

If configuring for Android:

  1. Modify AndroidManifest.xml: Add the intent filter inside the <activity> tag for .MainActivity.
xml
<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="http" android:host="yourdomain.com" />    <data android:scheme="https" /></intent-filter>
  1. Host assetlinks.json: Serve the following JSON at https://yourdomain.com/.well-known/assetlinks.json.
json
[{  "relation": ["delegate_permission/common.handle_all_urls"],  "target": {    "namespace": "android_app",    "package_name": "com.yourcompany.yourapp",    "sha256_cert_fingerprints": ["YOUR_SHA256_FINGERPRINT"]  }}]

If configuring for iOS:

  1. Modify Info.plist: Opt-in to Flutter's default deep link handler. Note: If using a third-party deep linking plugin (e.g., app_links), set this to NO to prevent conflicts.
xml
<key>FlutterDeepLinkingEnabled</key><true/>
  1. Modify Runner.entitlements: Add the associated domain.
xml
<key>com.apple.developer.associated-domains</key><array>  <string>applinks:yourdomain.com</string></array>
  1. Host apple-app-site-association: Serve the following JSON (without a .json extension) at https://yourdomain.com/.well-known/apple-app-site-association.
json
{  "applinks": {    "apps": [],    "details": [{      "appIDs": ["TEAM_ID.com.yourcompany.yourapp"],      "paths": ["*"],      "components": [{"/": "/*"}]    }]  }}

Validation Loop

Run validator -> review errors -> fix.

  • Android: Test using ADB.
    bash
    adb shell 'am start -a android.intent.action.VIEW -c android.intent.category.BROWSABLE -d "https://yourdomain.com/details/123"' com.yourcompany.yourapp
  • iOS: Test using xcrun on a booted simulator.
    bash
    xcrun simctl openurl booted https://yourdomain.com/details/123

Workflow: Implementing Nested Navigation

Use StatefulShellRoute to implement persistent UI shells (like a bottom navigation bar) that maintain the state of their child routes.

Task Progress

  • Define StatefulShellRoute.indexedStack in the GoRouter configuration.
  • Create StatefulShellBranch instances for each navigation tab.
  • Implement the shell widget using StatefulNavigationShell.
dart
final GoRouter _router = GoRouter(  initialLocation: '/home',  routes: [    StatefulShellRoute.indexedStack(      builder: (context, state, navigationShell) {        return ScaffoldWithNavBar(navigationShell: navigationShell);      },      branches: [        StatefulShellBranch(          routes: [            GoRoute(              path: '/home',              builder: (context, state) => const HomeScreen(),            ),          ],        ),        StatefulShellBranch(          routes: [            GoRoute(              path: '/settings',              builder: (context, state) => const SettingsScreen(),            ),          ],        ),      ],    ),  ],);

Examples

High-Fidelity Shell Widget Implementation

Implement the UI shell that consumes the StatefulNavigationShell to handle branch switching.

dart
class ScaffoldWithNavBar extends StatelessWidget {  const ScaffoldWithNavBar({    required this.navigationShell,    super.key,  });
  final StatefulNavigationShell navigationShell;
  void _goBranch(int index) {    navigationShell.goBranch(      index,      // Support navigating to the initial location when tapping the active tab.      initialLocation: index == navigationShell.currentIndex,    );  }
  @override  Widget build(BuildContext context) {    return Scaffold(      body: navigationShell,      bottomNavigationBar: NavigationBar(        selectedIndex: navigationShell.currentIndex,        onDestinationSelected: _goBranch,        destinations: const [          NavigationDestination(icon: Icon(Icons.home), label: 'Home'),          NavigationDestination(icon: Icon(Icons.settings), label: 'Settings'),        ],      ),    );  }}

Programmatic Navigation

Use the context.go() and context.push() extension methods provided by go_router.

dart
// Replaces the current route stack with the target route (Declarative)context.go('/details/123');
// Pushes the target route onto the existing stack (Imperative)context.push('/details/123');
// Navigates using a named route and path parameterscontext.goNamed('details', pathParameters: {'id': '123'});
// Pops the current routecontext.pop();

來源與署名

來源:flutter/agent-plugins位於skills/flutter-setup-declarative-routing提交0ef3972

授權條款: 無授權條款

內容歸原作者所有。SourceWeft 從公開儲存庫中收錄這些內容。

檢舉或申請下架