orbital_router 0.2.1 copy "orbital_router: ^0.2.1" to clipboard
orbital_router: ^0.2.1 copied to clipboard

Flutter router integration for Orbital modules, scopes and deep links.

orbital_router #

Flutter routing integration for Orbital modules, scopes, deep links and navigation guards.

Imports #

orbital_router exports the routing API plus the core contracts used by route declarations.

If you want the default scope runtime, import orbital_injector as well:

import 'package:orbital_injector/orbital_injector.dart';
import 'package:orbital_router/orbital_router.dart';

If you prefer a single import surface, use package:orbital/orbital.dart.

What this package contains #

orbital_router connects the Orbital scope model to Flutter navigation:

  • OrbitalRouter(...)
  • OrbitalRouter.routingConfig(...)
  • OrbitalModule, OrbitalPageRoute and OrbitalModuleRoute
  • OrbitalRouterDelegate
  • OrbitalRouteContext
  • OrbitalMiddleware and OrbitalAsyncMiddleware
  • OrbitalRetentionPolicy
  • OrbitalReactivationPolicy
  • OrbitalScopeFactory
  • OrbitalScopeProvider plus BuildContext extensions
  • router debug snapshots consumed by orbital_devtools

Quick start #

final router = OrbitalRouter(
  scopeFactory: const DefaultOrbitalScopeFactory(),
  initialUri: Uri.parse('/'),
  modules: [
    OrbitalModule(
      path: '/',
      routes: [
        OrbitalPageRoute(
          path: '/home',
          builder: (context, routeContext) => const HomePage(),
        ),
      ],
    ),
  ],
);

MaterialApp.router(
  routerConfig: router,
);

Keep the OrbitalRouter instance stable for the lifetime of the owning app state, and call router.dispose() from State.dispose() when you create it manually.

Pass onNavigationError to observe navigation failures that happen mid-session (after the router has already committed to a route) without disrupting the currently visible page:

OrbitalRouter(
  // ...
  onNavigationError: (error) => scaffoldMessengerKey.currentState
      ?.showSnackBar(SnackBar(content: Text('Navigation failed: $error'))),
);

Route tree model #

Orbital composes navigation from modules and page routes.

Modules contribute:

  • a base path
  • module-scoped bindings
  • module-scoped middlewares
  • nested pages or submodules

Pages contribute:

  • a page path
  • page-scoped bindings
  • page-scoped middlewares
  • a widget builder
  • optional retention semantics
  • optional route and async page presentation overrides

Matching and module identity #

Route matching prefers more specific branches first. Static segments outrank parameterized segments; declaration order is only the final tiebreaker.

OrbitalModule.id is the semantic identity used for scope reuse across rebuilt declarations. If you want a module scope to survive equivalent rebuilds, supply an explicit id.

Without id, reuse falls back to the module declaration identity inside the current delegate instance, which prevents unrelated modules that merely share the same path from accidentally reusing each other's scope.

Async navigation #

A branch is treated as async when it contains async bindings or async middlewares.

Use:

  • asyncNavigationBuilder
  • asyncNavigationPageFactory
  • pageFactory

Precedence is:

  • page
  • nearest module
  • app-level default

Custom pageFactory and asyncNavigationPageFactory implementations must return a Page that preserves the supplied key. Orbital relies on that key to keep Navigator.pages identity stable across pops, redirects and rebuilds.

During async navigation, Orbital keeps the currently rendered route mounted under the async page by default. The fallback async page is non-opaque, so the active page remains visible unless a custom async page factory chooses a different presentation.

OrbitalAsyncNavigationState.background remains available for custom builders that want to compose an explicit background widget.

Middleware #

OrbitalMiddleware can:

  • continue navigation
  • block navigation
  • redirect to another URI

Hook points:

  • onBeforeRun
  • onAfterRun

Middlewares that may await must implement OrbitalAsyncMiddleware.

Guards currently run after Orbital has resolved the destination module and page scopes. This keeps guard code able to read scoped dependencies, but it also means a blocked navigation may pay the initialization cost for the attempted destination. Keep heavy or side-effecting initialization out of guarded bindings when unauthenticated users commonly hit those routes.

Scope access and navigation helpers #

Pages can read route and scope state from:

  • OrbitalRouteContext
  • context.orbitalRouteContext
  • context.orbitalScope
  • context.getOrbital<T>()
  • context.pushNamed('/path')
  • context.pushReplacementNamed('/path')
  • context.pushNamedAndRemoveAll('/path')

Orbital now renders a real Navigator.pages stack.

  • pushNamed / pushUri push a new page entry
  • pushReplacementNamed / pushReplacementUri replace only the top entry
  • pushNamedAndRemoveAll / pushUriAndRemoveAll reset the stack to a single destination
  • pop() / popRoute() / popUntil(...) remove stack entries and reactivate the previous one

By default, reactivation preserves page and module scopes exactly as they were. OrbitalReactivationPolicy can opt routes or modules into rerunning middlewares when a stacked entry becomes active again. Precedence is router, then outer-to-inner modules, then the page route.

When OrbitalRouter.routingConfig(...) changes but all live entries still match the new route tree, Orbital preserves the current stack instead of collapsing it to a single page. If the active URI disappears from the new config, Orbital shows the configured not-found page for that URI and clears invalid stack entries.

On the web, browser back/forward route information is currently treated as a replace-all platform route update. Orbital does not yet restore the logical page stack from RouteInformation.state, so browser history should be considered URL-level navigation rather than full in-memory stack restoration.

Retention and scope rules #

  • page bindings require createScope: true
  • persistent module and page scopes can be retained across navigations
  • page retention keys default to path + query + fragment
  • persistentScopeKeyBuilder lets apps override page retention semantics
  • OrbitalRetentionPolicy bounds retained module/page entries and evicts the oldest retained scope when capacity is exceeded

More detail #

See doc.md for lifecycle flow, stack reactivation, middleware orchestration, async overlay behavior and error semantics.

0
likes
0
points
416
downloads

Publisher

unverified uploader

Weekly Downloads

Flutter router integration for Orbital modules, scopes and deep links.

Repository (GitHub)
View/report issues

License

unknown (license)

Dependencies

flutter, meta, orbital_core

More

Packages that depend on orbital_router