route-config
Configures routes with the IRoute / CustomRouter abstractions in core and exposes navigation via a BuildContext coordinator
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
Configures routes with the IRoute / CustomRouter abstractions in core and exposes navigation via a BuildContext coordinator
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
Handles cross-feature BusEvent communication with EventBusManager in the Flutter base template
Implements BLoC state management using AppBlocBase, an abstract State hierarchy, and a freezed _StateData
Builds the data layer with Freezed DTOs, Retrofit clients, hive_ce local stores, and repositories wired through injectable
Reviews UI-layer changes — screens, blocs, widgets, routes — against the template's StateBase + AppBlocBase + fl_theme conventions
Adds and updates app strings through the CSV → ARB → generated localizations workflow
Scaffolds a new feature module under apps/main/lib/presentation/modules using the bundled module generator
| name | route-config |
| description | Configures routes with the IRoute / CustomRouter abstractions in core and exposes navigation via a BuildContext coordinator |
| license | MIT |
| compatibility | all |
| metadata | {"audience":"flutter-developers","framework":"flutter","pattern":"navigation"} |
Defined in core/lib/presentation/route/route.dart and re-exported via package:core/core.dart:
IRoute — module-level provider; implements routers() returning List<CustomRouter>.CustomRouter<T> — one route entry, parameterized on the type of extra. Supports path, builder, extraFromUrlQueries, and pathVerify.Navigation is invoked via PushBehavior strategies (PushNamedBehavior, GoBehavior, etc.) over a BuildContext extension — the "coordinator" pattern.
The plugin plugins/fl_navigation/ ships a richer variant (with routes:, redirect:, toGoRoute() bridges) but is not imported by apps/ or core/ here — feature code uses the core variant only.
Do not import package:go_router/go_router.dart directly from feature code. Go through IRoute/CustomRouter.
import 'package:core/core.dart';
import '../../../di/di.dart';
import 'bloc/feature_bloc.dart';
import 'views/feature_screen.dart';
class FeatureRoute extends IRoute {
@override
List<CustomRouter> routers() {
return [
CustomRouter<FeatureArgs>(
path: FeatureScreen.routeName,
builder: (context, uri, extra) {
final args = asOrNull<FeatureArgs>(extra);
return BlocProvider<FeatureBloc>(
create: (context) => injector.get(param1: args?.initial),
child: FeatureScreen(args: args),
);
},
extraFromUrlQueries: FeatureArgs.fromUrlParams,
),
];
}
}
The routeName lives on the screen as static String routeName = '/feature';. injector.get(param1: ...) flows the @factoryParam from the bloc constructor.
A parent IRoute aggregates child IRoutes with the spread operator:
class DashboardRoute extends IRoute {
@override
List<CustomRouter> routers() => [
...HomeRoute().routers(),
...AnalyticsRoute().routers(),
...SettingsRoute().routers(),
];
}
The app's top-level route registry (e.g. apps/main/lib/presentation/route/route.dart) does the same to bring every module into the router.
Detail-style screens use a typed Args class so navigation can be either object-driven or deep-link-driven:
class FeatureArgs {
final Item? initial;
final String? id;
FeatureArgs({this.initial, this.id});
factory FeatureArgs.fromUrlParams(Map<String, dynamic> queryParameters) =>
FeatureArgs(id: asOrNull(queryParameters['id']));
// For web, flatten to a query map; for native, pass the rich object.
dynamic get adaptive {
if (kIsWeb) {
return {'id': initial?.id ?? id}..removeWhere((_, v) => v.isNullOrEmpty);
}
return this;
}
}
CustomRouter.buildExtra resolves either path: a real Args object passed via arguments, or query params on a deep link.
Every module exposes its routes through a BuildContext extension so callers don't typo route paths:
import 'package:core/core.dart';
import 'package:flutter/material.dart';
import 'feature.dart';
extension FeatureCoordinator on BuildContext {
Future<T?> goToFeature<T>({
required Item object,
PushBehavior pushBehavior = const PushNamedBehavior(),
}) async {
return pushBehavior.push(
this,
FeatureScreen.routeName,
arguments: FeatureArgs(initial: object).adaptive,
);
}
Future<T?> goToFeatureById<T>({
required String id,
PushBehavior pushBehavior = const PushNamedBehavior(),
}) async {
return pushBehavior.push(
this,
FeatureScreen.routeName,
arguments: FeatureArgs(id: id).adaptive,
);
}
}
Callers: context.goToFeature(object: item) or context.goToFeatureById(id: '42').
static String routeName starting with /.IRoute and uses CustomRouter<Args> (typed) when extras are non-null.BlocProvider and creates the bloc via injector.get(...).extraFromUrlQueries provided when the screen should be deep-linkable.goToX methods, all taking PushBehavior.IRoute registered in the parent / app-level IRoute.package:go_router/go_router.dart imports in feature code.routers() into the parent.extra without an Args type, then casting in the screen — it loses URL-param support.