flutter-routing-and-navigation — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited flutter-routing-and-navigation (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
an Activity in Android or a ViewController in iOS.
Navigator (Imperative) for small applications without complex deep linking requirements. It manages a stack ofRoute objects.
Router (Declarative) for applications with advanced navigation, web URL synchronization, and specific deeplinking requirements.
Web. Web requires no additional setup.
MaterialApp.routes and Navigator.pushNamed) for most applications. Theyhave rigid deep linking behavior and do not support the browser forward button. Use a routing package like go_router instead.
Use the Navigator widget to push and pop routes using platform-specific transition animations (MaterialPageRoute or CupertinoPageRoute).
#### Pushing and Popping
Navigator.push(context, route).Navigator.pop(context).Navigator.pushReplacement() to replace the current route, or Navigator.pushAndRemoveUntil() to clear the stackbased on a condition.
#### Passing and Returning Data
settings: RouteSettings(arguments: data) parameter of the PageRoute and extract it using ModalRoute.of(context)!.settings.arguments.
pop method: Navigator.pop(context, resultData). Await the result onthe pushing side: final result = await Navigator.push(...).
For apps requiring deep linking, web URL support, or complex routing, implement the Router API via a declarative routing package like go_router.
MaterialApp to MaterialApp.router.Navigator automatically.context.go('/path')).dialogs, bottom sheets) are pageless. Removing a page-backed route automatically removes all subsequent pageless routes.
Implement nested navigation to manage a sub-flow of screens (e.g., a multi-step setup process or persistent bottom navigation tabs) independently from the top-level global navigator.
Navigator widget inside the host widget.GlobalKey<NavigatorState> to the nested Navigator to control it programmatically.onGenerateRoute callback within the nested Navigator to resolve sub-routes.PopScope to prevent the top-level navigator from popping the entirenested flow prematurely.
#### Workflow: Standard Screen Transition Copy this checklist to track progress when implementing a basic screen transition:
Navigator.push() in the source widget.MaterialPageRoute or CupertinoPageRoute.Navigator.pop() in the destination widget to return.#### Workflow: Implementing Deep-Linkable Routing Use this conditional workflow when setting up app-wide routing:
MaterialApp and Navigator.push().go_router package.MaterialApp to MaterialApp.router.GoRouter configuration with all top-level routes.Navigator.push() with context.go() or context.push().#### Workflow: Creating a Nested Navigation Flow Run this workflow when building a multi-step sub-flow (e.g., IoT device setup):
GlobalKey<NavigatorState> in the host widget's state.Navigator widget in the host's build method, passing the key.onGenerateRoute in the nested Navigator to map string paths to specific step widgets.Scaffold in a PopScope to handle back-button interceptions (e.g., prompting an exitconfirmation; route the prompt text through AppLocalizations, never a literal).
navigatorKey.currentState?.pushNamed() to advance steps within the flow. The force-unwrap ! is banned;guard the nullable state or use ?..
#### Example: Passing Data via Constructor (Imperative)
// 1. Define the data model
class Todo {
final String title;
final String description;
const Todo(this.title, this.description);
}
// 2. Source Screen
class TodosScreen extends StatelessWidget {
final List<Todo> todos;
const TodosScreen({super.key, required this.todos});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Todos')),
body: ListView.builder(
itemCount: todos.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(todos[index].title),
onTap: () {
// Push and pass data via constructor
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => DetailScreen(todo: todos[index]),
),
);
},
);
},
),
);
}
}
// 3. Destination Screen
class DetailScreen extends StatelessWidget {
final Todo todo;
const DetailScreen({super.key, required this.todo});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text(todo.title)),
body: Padding(
padding: const EdgeInsets.all(16),
child: Text(todo.description),
),
);
}
}#### Example: Nested Navigation Flow
class SetupFlow extends StatefulWidget {
final String initialRoute;
const SetupFlow({super.key, required this.initialRoute});
@override
State<SetupFlow> createState() => _SetupFlowState();
}
class _SetupFlowState extends State<SetupFlow> {
final _navigatorKey = GlobalKey<NavigatorState>();
void _exitSetup() => Navigator.of(context).pop();
@override
Widget build(BuildContext context) {
return PopScope(
canPop: false,
onPopInvokedWithResult: (didPop, _) async {
if (didPop) return;
// Intercept back button to prevent accidental exit
_exitSetup();
},
child: Scaffold(
appBar: AppBar(title: const Text('Setup')),
body: Navigator(
key: _navigatorKey,
initialRoute: widget.initialRoute,
onGenerateRoute: _onGenerateRoute,
),
),
);
}
Route<Widget> _onGenerateRoute(RouteSettings settings) {
Widget page;
switch (settings.name) {
case 'step1':
page = StepOnePage(
// No force-unwrap: guard the nullable navigator state.
onComplete: () => _navigatorKey.currentState?.pushNamed('step2'),
);
break;
case 'step2':
page = StepTwoPage(onComplete: _exitSetup);
break;
default:
throw StateError('Unexpected route name: ${settings.name}!');
}
return MaterialPageRoute(
builder: (context) => page,
settings: settings,
);
}
}~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.