router_builder 2.0.1
router_builder: ^2.0.1 copied to clipboard
Declarative Flutter navigation and deep link generator with typed routes.
Router Builder #
Router Builder simplifies Flutter route management and deep linking through code generation. Define your routes once, and let the generator handle the boilerplate.
Features #
- π Code Generation: Automatically generates route helpers from annotations
- π Unified Deep Links: Routes and deep links defined in one place
- π‘οΈ Type Safety: Strongly typed route definitions and navigation
- β‘ Build-time Validation: Detects route conflicts during generation
- π― Simple API: Clean, intuitive route definition syntax
- π·οΈ Localized Titles: Optional
titlecallback for per-route titles that react to locale changes
Getting Started #
Installation #
Add to your pubspec.yaml:
dependencies:
router_builder: ^2.0.1
dev_dependencies:
build_runner: ^2.10.1
Basic Usage #
- Define your routes using the
@RT()annotation:
import 'package:router_builder/router_builder.dart';
import 'screens/home_screen.dart';
import 'screens/profile_screen.dart';
class AppRoutes {
@RT()
static final home = RouteInfo(
'home',
title: (context, [args]) => context.tr.homeTitle,
builder: (context, args) => HomeScreen(),
);
@RT()
static final profile = RouteInfo(
'profile',
path: 'profile/:id',
title: (context, [args]) => context.tr.profileTitle,
builder: (context, args) => ProfileScreen(userId: args?.id),
deepLinkNames: ['user'], // Alternative deep link: /user/:id
);
}
- Run the generator:
flutter pub run build_runner build --delete-conflicting-outputs
- Use generated helpers in your router:
import 'route_info_helper.dart'; // Generated file
// Access routes
final homeRoute = MyRoutes.home;
final profileRoute = MyRoutes.profile;
// Get route by name
final route = RouteInfoHelper.fromName('profile');
// Access deep link map
final deepLinkMap = RouteInfoHelper.deepLinkMap;
RouteArgs conveniences #
pathParams: Map of named path params (e.g., forpost/:postId/comment/:commentId).fromUri: Build args from aUriand aRouteInfotemplate.
final args = RouteArgs.fromUri(MyRoutes.profile, Uri.parse('/profile/123?tab=posts'));
print(args.id); // '123'
print(args.queryParams); // { 'tab': 'posts' }
print(args.pathParams); // { }
Interception and resume #
You can capture an intended navigation and pass it as a resume intent to another route (e.g., Auth). After the prerequisite flow completes, resume navigation using the stored intent.
// Intended destination (protected)
final intended = RouteArgs(
MyRoutes.profile,
id: '123',
queryParams: {'tab': 'posts'},
object: UserPreview(...),
);
// Guard interception example (pseudo-code)
final isAllowed = authService.isLoggedIn;
if (!isAllowed) {
// Navigate to auth with a resume intent
final authArgs = RouteArgs(MyRoutes.auth, resumeTo: intended);
navigation.push(authArgs);
return; // Block original navigation
}
// After successful login, resume
void onAuthSuccess(RouteArgs authArgs) {
final next = authArgs.resumeTo;
if (next != null) navigation.replaceAll(next);
}
Hierarchical names #
RouteInfo.generateName(parentRoute: ...) uses dot notation for names: parent.child.
Paths continue to use slash notation and default to "/name" unless overridden by path.
Deep Link Integration #
Routes automatically support deep linking:
@RT()
static final referral = RouteInfo(
'referral',
path: 'referral/:code',
title: (context, [args]) => context.tr.referralTitle,
builder: (context, args) => ReferralScreen(code: args?.id),
deepLinkHandler: const ReferralDeepLinkHandler(), // Custom logic
);
// Custom handler for complex deep links
class ReferralDeepLinkHandler extends DeepLinkHandler<MyAction> {
const ReferralDeepLinkHandler();
@override
bool canHandle(Uri uri) => true;
@override
MyAction? createAction(Uri uri, RouteInfo route) {
final code = uri.pathSegments.last;
return SaveReferralCodeAction(code: code);
}
}
Branch Routes (Tab Navigation) #
Define routes for navigation shells:
enum NavigationTab { home, explore, profile }
@RT()
static const homeTab = RouteInfo.branch(
'home',
branchParentType: NavigationTab.home,
branchIndex: 0,
branchKey: 'home_branch',
builder: (context, args) => HomeTab(),
isTopLevelOnly: true,
);
Migration Guide #
See MIGRATION_GUIDE.md for migrating from separate deep link registries.
License #
This project is licensed under the MIT License.