route_next 1.2.1
route_next: ^1.2.1 copied to clipboard
Next.js-style Flutter router — URL-driven navigation, nested layouts, global middleware, async guards, breadcrumbs, command palette, and tab bar.
1.2.1 #
New Features #
- Global middleware pipeline: Add app-wide
middlewaretoRouteNextApp— runs before per-route guards on every navigation. Compose analytics, auth gates, and feature flags without attaching guards to individual routes.RouteNextApp( middleware: [ (context, match) async { Analytics.track(match.resolvedPath); return NavigationAction.allow(); }, ], routes: [...], ) RouteNextBreadcrumbs: Auto-generated breadcrumb trail driven byRouteMatch.matchChain. Labels are derived fromRouteMeta.title, a customlabelBuilder, or the capitalised path segment. Supports custom separators, text styles, and padding.RouteNextCommandPalette: ⌘K / Ctrl+K command palette overlay. Supports fuzzy substring search, keyboard navigation (↑↓ Enter Esc), group badges, and both route navigation and arbitraryonSelectcallbacks.RouteNextTabBar: URL-driven tab bar where the active tab is determined byRouteNext.isActive(). Works as a standalone widget or asAppBar.bottomvia.asPreferredSize(). Supports scrollable mode, custom colors, and icon+label tabs. Correctly hides the indicator when no tab matches the current URL.
Bug Fixes #
RouteNextCommandPalette— FocusNode memory leaks: TwoFocusNodeinstances were previously created inline insidebuild()methods (both in_RouteNextCommandPaletteStateand_PaletteOverlayState), causing a new unmanaged node to be allocated on every rebuild. Fixed by promoting both to named fields disposed in their respectivedispose()methods.RouteNextTabBar— ghost active tab: When the current URL matched none of the tabs,activeIndexfell back to0, causing the first tab to appear falsely selected. Fixed by trackinghasActiveTabseparately; whenfalse, the indicator and label color are both suppressed.
1.2.0 #
Bug Fixes #
- Critical — Navigator key crash fixed: Dart
Map.==uses reference equality, so the duplicate-detection logic in_commitToStackandsetNewRoutePathalways evaluated to false, allowing duplicatePageentries with identicalLocalKeys to enter the Navigator'spageslist and trigger the!keyReservation.contains(key)assertion crash. Fixed by introducing a_mapsEqualhelper that performs value-based comparison. onDidRemovePagedouble-remove: When the delegate shortened the stack and callednotifyListeners(), Flutter's reconciliation also firedonDidRemovePage, causing the handler to remove the same entry a second time and leave a blank screen. Fixed by guarding removal withpage.key == _pageKey(_stack.last).- Page key string-concat collision:
ValueKey(resolvedPath + extra.hashCode.toString())could produce identical keys for logically distinct routes (e.g. path/a1with no extra vs path/awhose extra hashashCode == 1). Fixed by using a Dart record tuple:ValueKey((resolvedPath, extra?.hashCode)). replace()bypassing deduplication:replace()manipulated_stackdirectly instead of routing through_commitToStack, allowing duplicate resolved paths to accumulate. Fixed by routing through the central_commitToStackhelper.- Guard redirect to existing stack entry: When a guard redirected to a path already present in the stack,
_handleNewPathappended a duplicate entry directly via_stack.add, bypassing deduplication. Fixed by routing all commits through_commitToStack. RouteNextProvider.updateShouldNotifyignoringextra: Widget subtrees that depended onextradid not rebuild when onlyextrachanged becauseupdateShouldNotifyonly comparedcurrentMatchobject identity. Fixed by also comparingcurrentMatch?.extra.
Breaking Changes #
- Minimum Flutter version raised to
>=3.27.0(was>=3.16.0). Required byColor.withValues(alpha:)usage in built-in UI components (Sidebar, Drawer). Users on Flutter < 3.27 should stay on1.1.0or upgrade Flutter.
Tests #
- Added 19 new regression tests in
test/widgets/route_next_delegate_test.dartcovering all of the above bug scenarios: back-navigation stack integrity, replace-mode deduplication, page-key collision, guard redirect loops,onDidRemovePageinteraction,isActivematching, and 404 fallback rendering.
1.1.0 #
- Architecture Refined: Significantly improved the core navigation engine for production readiness.
- Smart History Sync: Optimized
RouteNextDelegateto intelligently reconcile the internal stack with browser back/forward navigation. - Persistent Layouts: Shared layouts (Sidebars, Navbars) now maintain their internal state (scroll, focus) during navigation between child routes.
- Hierarchical Metadata: Introduced
matchChaininRouteMatchfor robust breadcrumb support and parent route awareness. - Improved
isActive: Refined the active status logic to support both pattern and resolved path matching across the entire route hierarchy. - Enhanced Example: Rebuilt the example project to demonstrate best practices for guards and nested layouts.
1.0.0 #
- Initial release of RouteNext.
- URL-first navigation powered by Navigator 2.0.
- Browser refresh and deep-linking support.
- Support for nested routes and layouts.
- Async route guards (middleware).
- Pattern matching with dynamic params (:id) and wildcards (*).
- Built-in UI components: RouteNextScaffold, Sidebar, Drawer, and Navbar.