flutter-setup-declarative-routing
`go_router` などのパッケージを使用して `MaterialApp.router` を設定し、URLベースの高度なナビゲーションを実現します。ディープリンクやブラウザ履歴のサポートが必要なWebアプリやモバイルアプリを開発する際に活用してください。
description の原文を見る
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.
SKILL.md 本文
ルーティングとディープリンクの実装
目次
コアコンセプト
Flutter でのデクララティブルーティングには go_router パッケージを使用します。複雑なルーティングシナリオ、ディープリンク、ネストされたナビゲーションに対応した堅牢な API を提供します。
- GoRouter: アプリケーションのルートツリーを定義する中央設定オブジェクト。
- GoRoute: URL パスを Flutter スクリーンにマッピングする標準ルート。
- ShellRoute / StatefulShellRoute: 子ルートを永続的な UI シェル(例:
BottomNavigationBar)でラップします。StatefulShellRouteは並列ナビゲーションブランチの状態を維持します。 - Path URL Strategy: Web URL からデフォルトの
#フラグメントを削除し、プラットフォーム全体でのクリーンなディープリンクを実現します。
ワークフロー: アプリケーションとルーターの初期化
このワークフローに従い、go_router を使用した新しい Flutter アプリケーションを起動し、ルートルーティングメカニズムを設定します。
タスク進捗
- Flutter アプリケーションを作成する。
-
go_router依存関係を追加する。 - Web/ディープリンク用の URL strategy を設定する。
-
GoRouter設定を実装する。 - ルーターを
MaterialApp.routerにバインドする。
1. アプリケーションのスキャフォルド
次のコマンドを実行してアプリを作成し、必要なルーティングパッケージを追加します:
flutter create <app-name>
cd <app-name>
flutter pub add go_router
2. ルーターを設定
トップレベルの GoRouter インスタンスを定義します。redirect パラメータを使用して認証またはステート ベースのルーティングを処理します。
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import 'package:flutter_web_plugins/url_strategy.dart';
void main() {
// Web URL から '#' を削除するため path URL strategy を使用
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',
);
}
}
ワークフロー: プラットフォームのディープリンク設定
ネイティブプラットフォームを設定して特定の URL をインターセプトし、Flutter アプリケーションにルーティングします。
タスク進捗
- ターゲットプラットフォーム(iOS、Android、またはその両方)を決定する。
- Android の条件付き設定を適用する(Manifest + Asset Links)。
- iOS の条件付き設定を適用する(Plist + Entitlements + AASA)。
- バリデータを実行 → エラーを確認 → 修正する。
Android 用に設定する場合:
AndroidManifest.xmlを変更:.MainActivityの<activity>タグ内に intent filter を追加します。
<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>
assetlinks.jsonをホスト: 次の JSON をhttps://yourdomain.com/.well-known/assetlinks.jsonで提供します。
[{
"relation": ["delegate_permission/common.handle_all_urls"],
"target": {
"namespace": "android_app",
"package_name": "com.yourcompany.yourapp",
"sha256_cert_fingerprints": ["YOUR_SHA256_FINGERPRINT"]
}
}]
iOS 用に設定する場合:
Info.plistを変更: Flutter のデフォルトディープリンクハンドラーをオプトインします。 注: サードパーティのディープリンキングプラグイン(例:app_links)を使用している場合は、競合を防ぐためこれをNOに設定してください。
<key>FlutterDeepLinkingEnabled</key>
<true/>
Runner.entitlementsを変更: associated domain を追加します。
<key>com.apple.developer.associated-domains</key>
<array>
<string>applinks:yourdomain.com</string>
</array>
apple-app-site-associationをホスト: 次の JSON を(.json拡張子なしで)https://yourdomain.com/.well-known/apple-app-site-associationで提供します。
{
"applinks": {
"apps": [],
"details": [{
"appIDs": ["TEAM_ID.com.yourcompany.yourapp"],
"paths": ["*"],
"components": [{"/": "/*"}]
}]
}
}
バリデーションループ
バリデータを実行 → エラーを確認 → 修正する。
- Android: ADB を使用してテストします。
adb shell 'am start -a android.intent.action.VIEW -c android.intent.category.BROWSABLE -d "https://yourdomain.com/details/123"' com.yourcompany.yourapp - iOS: 起動されたシミュレータで
xcrunを使用してテストします。xcrun simctl openurl booted https://yourdomain.com/details/123
ワークフロー: ネストされたナビゲーションの実装
StatefulShellRoute を使用して、永続的な UI シェル(ボトムナビゲーションバーなど)を実装し、子ルートの状態を維持します。
タスク進捗
-
GoRouter設定でStatefulShellRoute.indexedStackを定義する。 - 各ナビゲーションタブに対して
StatefulShellBranchインスタンスを作成する。 -
StatefulNavigationShellを使用してシェルウィジェットを実装する。
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(),
),
],
),
],
),
],
);
例
高忠実度シェルウィジェットの実装
StatefulNavigationShell を使用して、ブランチ切り替えを処理する UI シェルを実装します。
class ScaffoldWithNavBar extends StatelessWidget {
const ScaffoldWithNavBar({
required this.navigationShell,
super.key,
});
final StatefulNavigationShell navigationShell;
void _goBranch(int index) {
navigationShell.goBranch(
index,
// アクティブなタブをタップする際、初期ロケーションへのナビゲーションをサポート
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'),
],
),
);
}
}
プログラマティックナビゲーション
go_router によって提供される context.go() および context.push() 拡張メソッドを使用します。
// 現在のルートスタックをターゲットルートで置き換える(デクララティブ)
context.go('/details/123');
// ターゲットルートを既存スタックにプッシュする(イムペラティブ)
context.push('/details/123');
// 名前付きルートとパスパラメータを使用してナビゲート
context.goNamed('details', pathParameters: {'id': '123'});
// 現在のルートをポップ
context.pop();
ライセンス: BSD-3-Clause(寛容ライセンスのため全文を引用しています) · 原本リポジトリ
詳細情報
- 作者
- flutter
- リポジトリ
- flutter/skills
- ライセンス
- BSD-3-Clause
- 最終更新
- 不明
Source: https://github.com/flutter/skills / ライセンス: BSD-3-Clause
関連スキル
doubt-driven-development
重要な判断はすべて、本番環境への展開前に新しい視点から対抗的レビューを実施します。速度より正確性が重要な場合、不慣れなコードを扱う場合、本番環境・セキュリティに関わるロジック・取り消し不可の操作など影響度が高い場合、または後でバグを修正するよりも今検証する方が効率的な場合に活用してください。
apprun-skills
TypeScriptを使用したAppRunアプリケーションのMVU設計に関する総合的なガイダンスが得られます。コンポーネントパターン、イベントハンドリング、状態管理(非同期ジェネレータを含む)、パラメータと保護機能を備えたルーティング・ナビゲーション、vistestを使用したテストに対応しています。AppRunコンポーネントの設計・レビュー、ルートの配線、状態フローの管理、AppRunテストの作成時に活用してください。
desloppify
コードベースのヘルスチェックと技術負債の追跡ツールです。コード品質、技術負債、デッドコード、大規模ファイル、ゴッドクラス、重複関数、コードスメル、命名規則の問題、インポートサイクル、結合度の問題についてユーザーが質問した場合に使用してください。また、ヘルススコアの確認、次の改善項目の提案、クリーンアップ計画の作成をリクエストされた際にも対応します。29言語に対応しています。
debugging-and-error-recovery
テストが失敗したり、ビルドが壊れたり、動作が期待と異なったり、予期しないエラーが発生したりした場合に、体系的な根本原因デバッグをガイドします。推測ではなく、根本原因を見つけて修正するための体系的なアプローチが必要な場合に使用してください。
test-driven-development
テスト駆動開発により実装を進めます。ロジックの実装、バグの修正、動作の変更など、あらゆる場面で活用できます。コードが正常に動作することを証明する必要がある場合、バグ報告を受けた場合、既存機能を修正する予定がある場合に使用してください。
incremental-implementation
変更を段階的に実施します。複数のファイルに影響する機能や変更を実装する場合に使用してください。大量のコードを一度に書こうとしている場合や、タスクが一度では完結できないほど大きい場合に活用します。