### Setup Flutter Project Source: https://github.com/slovnicki/beamer/blob/master/examples/books_dialogroute/README.md Initializes a new Flutter project in the current directory, generating all necessary files for the example application. This command should be run once to prepare the environment. ```Shell flutter create . ``` -------------------------------- ### Configuring Beamer with List of BeamStacks Source: https://github.com/slovnicki/beamer/blob/master/package/README.md This Dart example shows an alternative, simpler way to configure `BeamerDelegate` using `BeamerStackBuilder`. Instead of a custom function, it takes a list of `BeamStack` instances, allowing Beamer to automatically select the appropriate stack based on its defined `pathPatterns`. ```dart final routerDelegate = BeamerDelegate( stackBuilder: BeamerStackBuilder( beamStacks: [ HomeStack(), BooksStack(), ], ), ); ``` -------------------------------- ### Perform Reverse Chronological Navigation (Beam Back) Source: https://github.com/slovnicki/beamer/blob/master/package/README.md This example shows how to navigate back chronologically through Beamer's history using `Beamer.of(context).beamBack()`. This method differs from a simple 'pop' as it navigates to the previous entry in the `beamingHistory`, which is particularly useful in deep-linking scenarios. ```dart Beamer.of(context).beamBack(); ``` -------------------------------- ### Configuring Beamer with Custom StackBuilder Source: https://github.com/slovnicki/beamer/blob/master/package/README.md This Dart code illustrates the basic setup of a Flutter `MaterialApp.router` using Beamer. It defines a `BeamerDelegate` with a custom `stackBuilder` function that dynamically returns either a `BooksStack` or `HomeStack` based on the incoming URI path, demonstrating how to control which `BeamStack` handles a given route. ```dart class MyApp extends StatelessWidget { final routerDelegate = BeamerDelegate( stackBuilder: (routeInformation, _) { if (routeInformation.uri.path.contains('books')) { return BooksStack(routeInformation); } return HomeStack(routeInformation); }, ); @override Widget build(BuildContext context) { return MaterialApp.router( routerDelegate: routerDelegate, routeInformationParser: BeamerParser(), backButtonDispatcher: BeamerBackButtonDispatcher(delegate: routerDelegate), ); } } ``` -------------------------------- ### Perform Basic Beamer Navigation Source: https://github.com/slovnicki/beamer/blob/master/package/README.md This section illustrates various ways to perform forward navigation using Beamer. It covers basic `beamToNamed` calls, using an extension method on `BuildContext`, and how to pass additional data that persists throughout navigation within the same `BeamStack`. ```dart // Basic beaming Beamer.of(context).beamToNamed('/books/2'); // Beaming with an extension method on BuildContext context.beamToNamed('/books/2'); // Beaming with additional data that persist // throughout navigation within the same BeamStack context.beamToNamed('/book/2', data: MyObject()); ``` -------------------------------- ### Example of Nested Navigation with Beamer and Bottom Navigation Bar Source: https://github.com/slovnicki/beamer/blob/master/package/README.md This Dart code illustrates how to implement nested navigation using multiple `Beamer` instances, typically for scenarios like a bottom navigation bar. It shows how a `Beamer` can be placed within the widget tree with a `key` to manage its own navigation stack, independent of the root navigator, and how `BeamerDelegate` is configured for nested stacks. ```Dart class HomeScreen extends StatelessWidget { HomeScreen({Key? key}) : super(key: key); final _beamerKey = GlobalKey(); final _routerDelegate = BeamerDelegate( stackBuilder: BeamerStackBuilder( beamStacks: [ BooksStack(), ArticlesStack(), ], ), ); @override Widget build(BuildContext context) { return Scaffold( body: Beamer( key: _beamerKey, routerDelegate: _routerDelegate, ), bottomNavigationBar: BottomNavigationBarWidget( beamerKey: _beamerKey, ), ); } } class MyApp extends StatelessWidget { final routerDelegate = BeamerDelegate( initialPath: '/books', stackBuilder: RoutesStackBuilder( routes: { '*': (context, state, data) => HomeScreen(), }, ), ); @override Widget build(BuildContext context) { return MaterialApp.router( routerDelegate: routerDelegate, routeInformationParser: BeamerParser(), ); } } ``` -------------------------------- ### Beamer API Changes and Behavior in 0.12 Source: https://github.com/slovnicki/beamer/blob/master/package/README.md Details API changes and behavioral modifications in Beamer version 0.12, including the removal of `RootRouterDelegate` and changes to `beamBack` functionality. Provides guidance on how to adapt existing code. ```APIDOC - RootRouterDelegate removed; rename to BeamerDelegate. - If using RootRouterDelegate's homeBuilder, use SimpleLocationBuilder with routes: {'/': (context) => HomeScreen()}. - beamBack behavior changed to go to previous BeamState. - Use popBeamLocation() for old beamBack behavior (going to previous BeamLocation). ``` -------------------------------- ### Beamer Usage Tips and Troubleshooting Source: https://github.com/slovnicki/beamer/blob/master/package/README.md This section provides a collection of practical tips and addresses common issues encountered when using the Beamer navigation package. It covers topics such as URL hash removal, the behavior of replacement beaming, browser tab title management, and a known issue regarding state loss during hot reload. ```APIDOC General Tips: - Removing '#' from URL: Call `Beamer.setPathUrlStrategy()` before `runApp()`. - `beamToReplacement*` methods: Replace the current entry in both `beamingHistory` and browser history. - `BeamPage.title`: Used for setting the browser tab title by default; can be disabled via `BeamerDelegate.setBrowserTabTitle = false`. Common Issues: - Losing state on hot reload: Refer to GitHub issue #193 for details and potential solutions. ``` -------------------------------- ### Beamer Guard for Specific Authenticated Routes Source: https://github.com/slovnicki/beamer/blob/master/package/README.md This `BeamGuard` example shows how to protect specific routes, such as `/profile/*` and `/orders/*`, requiring user authentication. Unlike the previous example, it does not use `guardNonMatching`, meaning the guard only applies to the explicitly listed `pathBlueprints`. If the `check` fails, the user is redirected to `/login`. ```dart BeamGuard( pathBlueprints: ['/profile/*', '/orders/*'], check: (context, stack) => context.isUserAuthenticated(), beamToNamed: (origin, target) => '/login', ) ``` -------------------------------- ### Beamer Core Concepts and Architecture Overview Source: https://github.com/slovnicki/beamer/blob/master/package/README.md Provides a high-level overview of Beamer's architectural components and their roles in managing navigation. It describes how Beamer wraps Flutter's `Router` and utilizes `RouterDelegate` and `RouteInformationParser` to separate page stack building responsibilities among `BeamStack` instances, with `BeamerDelegate.stackBuilder` orchestrating the routing. ```APIDOC Beamer: - Role: Wrapper for Flutter's `Router`. - Components: Uses its own implementations for `RouterDelegate` and `RouteInformationParser`. - Goal: Separates responsibility of building page stacks for `Navigator.pages` into multiple classes with different states. BeamStack: - Role: Handles specific sets of related page stacks (e.g., profile-related, shop-related). - Functionality: Knows which 'state' corresponds to which page stack. - Example Stacks: - Profile: `[ ProfilePage ]`, `[ ProfilePage, FriendsPage]`, `[ ProfilePage, FriendsPage, FriendDetailsPage ]`, `[ ProfilePage, SettingsPage ]` - Shop: `[ ShopPage ]`, `[ ShopPage, CategoriesPage ]`, `[ ShopPage, CategoriesPage, ItemsPage ]`, `[ ShopPage, CategoriesPage, ItemsPage, ItemDetailsPage ]`, `[ ShopPage, ItemsPage, ItemDetailsPage ]`, `[ ShopPage, CartPage ]` BeamerDelegate.stackBuilder: - Role: Decides which `BeamStack` will handle incoming `RouteInformation`. - Input: `RouteInformation` (from deep-link, initial route, or beaming). - Logic: Routes `RouteInformation` to appropriate `BeamStack` based on `pathPatterns` it supports. - Outcome: `BeamStack` creates and saves its own `state` from the `RouteInformation` to use for building a page stack. ``` -------------------------------- ### Beamer Core Concepts: BeamStack and BeamPage Source: https://github.com/slovnicki/beamer/blob/master/package/README.md This section outlines the fundamental components of Beamer navigation: `BeamStack` and `BeamPage`. It explains their roles in defining navigation paths and building UI pages, including how `BeamStack` manages URI parameters and how `BeamPage` configures individual screens with keys and transition types. ```APIDOC BeamStack: - Purpose: Handles which URI maps to which stack of pages. - Methods to implement: - `pathPatterns`: Defines URI patterns that this `BeamStack` handles. - `buildPages`: Returns a list of `BeamPage`s that form the navigation stack. - Properties: - `BeamState`: Stores query and path parameters from the URI. - Note: `:` is necessary in `pathPatterns` for path parameters. BeamPage: - Purpose: Represents a single screen/page in the application. - Properties: - `child`: An arbitrary `Widget` representing the page's UI. - `key`: Crucial for `Navigator` optimization; must be a unique `ValueKey` for page state. - `type`: (Optional) Specifies the transition type (e.g., `MaterialPageRoute` by default, or other `BeamPageType`s). ``` -------------------------------- ### Configure Beamer with RoutesStackBuilder and a Map of Routes Source: https://github.com/slovnicki/beamer/blob/master/package/README.md This Dart code demonstrates how to set up a `BeamerDelegate` using `RoutesStackBuilder` to define routes with a simple map. It supports wildcards and path parameters, allowing for flexible routing without custom `BeamStack` implementations. ```Dart final routerDelegate = BeamerDelegate( stackBuilder: RoutesStackBuilder( routes: { '/': (context, state, data) => HomeScreen(), '/books': (context, state, data) => BooksScreen(), '/books/:bookId': (context, state, data) => BookDetailsScreen( bookId: state.pathParameters['bookId'], ), }, ), ); ``` -------------------------------- ### Beamer API Renames in 0.13 Source: https://github.com/slovnicki/beamer/blob/master/package/README.md Summary of API class and method renames introduced in Beamer version 0.13 for better consistency and clarity. ```APIDOC - BeamerRouterDelegate renamed to BeamerDelegate - BeamerRouteInformationParser renamed to BeamerParser - pagesBuilder renamed to buildPages - Beamer.of(context).currentLocation renamed to Beamer.of(context).currentBeamLocation ``` -------------------------------- ### Migrate SimpleLocationBuilder from Beamer 0.14 to 1.X Source: https://github.com/slovnicki/beamer/blob/master/package/README.md Demonstrates the change in `SimpleLocationBuilder` usage and its replacement with `RoutesLocationBuilder` in Beamer version 1.X. The route builder function now includes an additional `data` parameter. ```Dart locationBuilder: SimpleLocationBuilder( routes: { '/': (context, state) => MyWidget(), '/another': (context, state) => AnotherThatNeedsState(state) } ) ``` ```Dart locationBuilder: RoutesLocationBuilder( routes: { '/': (context, state, data) => MyWidget(), '/another': (context, state, data) => AnotherThatNeedsState(state) } ) ``` -------------------------------- ### Initialize Flutter Project Source: https://github.com/slovnicki/beamer/blob/master/examples/nested_navigation/README.md Run this command to create a new Flutter project in the current directory, setting up all necessary files and dependencies for development. ```bash flutter create . ``` -------------------------------- ### Beamer Guard for Unauthenticated Users (Non-Matching Paths) Source: https://github.com/slovnicki/beamer/blob/master/package/README.md This `BeamGuard` example demonstrates how to protect routes from unauthenticated users by redirecting them to `/login`. It uses `guardNonMatching: true` to apply the check to all paths that are NOT `/login`, preventing an infinite loop where `/login` itself is guarded. The `check` function determines authentication status, and `beamToNamed` specifies the redirection target. ```dart BeamGuard( // on which path patterns (from incoming routes) to perform the check pathPatterns: ['/login'], // perform the check on all patterns that **don't** have a match in pathPatterns guardNonMatching: true, // return false to redirect check: (context, stack) => context.isUserAuthenticated(), // where to redirect on a false check beamToNamed: (origin, target) => '/login', ) ``` -------------------------------- ### Initialize Flutter Project Source: https://github.com/slovnicki/beamer/blob/master/examples/bottom_navigation_multiple_beamers/README.md Initializes a new Flutter project in the current directory. This command generates all necessary files and the basic project structure required to run a Flutter application. ```Bash flutter create . ``` -------------------------------- ### Initialize Flutter Project Source: https://github.com/slovnicki/beamer/blob/master/package/example/README.md This command initializes a new Flutter project in the current directory, generating all necessary files and project structure for development. It should be run if the project files are missing. ```Shell flutter create . ``` -------------------------------- ### Configure Beamer with RoutesStackBuilder Source: https://github.com/slovnicki/beamer/blob/master/package/README.md This snippet demonstrates how to set up a Flutter application using Beamer's `RoutesStackBuilder` to define navigation routes. It shows how to map paths to screens, handle path parameters like `bookId`, and use `BeamPage` for custom page transitions and properties. ```dart class MyApp extends StatelessWidget { final routerDelegate = BeamerDelegate( stackBuilder: RoutesStackBuilder( routes: { // Return either Widgets or BeamPages if more customization is needed '/': (context, state, data) => HomeScreen(), '/books': (context, state, data) => BooksScreen(), '/books/:bookId': (context, state, data) { // Take the path parameter of interest from BeamState final bookId = state.pathParameters['bookId']!; // Collect arbitrary data that persists throughout navigation final info = (data as MyObject).info; // Use BeamPage to define custom behavior return BeamPage( key: ValueKey('book-$bookId'), title: 'A Book #$bookId', popToNamed: '/', type: BeamPageType.scaleTransition, child: BookDetailsScreen(bookId, info), ); } }, ), ); @override Widget build(BuildContext context) { return MaterialApp.router( routeInformationParser: BeamerParser(), routerDelegate: routerDelegate, ); } } ``` -------------------------------- ### Integrate Android Back Button with Beamer Source: https://github.com/slovnicki/beamer/blob/master/package/README.md Demonstrates how to configure Android's back button behavior with Beamer by setting a `BeamerBackButtonDispatcher` in `MaterialApp.router`. It explains the dispatcher's `pop` and `beamBack` fallback mechanism and configurable options like `alwaysBeamBack` and `fallbackToBeamBack`. ```dart MaterialApp.router( ... routerDelegate: beamerDelegate, backButtonDispatcher: BeamerBackButtonDispatcher(delegate: beamerDelegate), ) ``` -------------------------------- ### Initialize Flutter Project Source: https://github.com/slovnicki/beamer/blob/master/examples/firebase_auth/README.md Runs the `flutter create .` command to generate all necessary project files and prepare for Firebase configuration. This command should be executed in the project's root directory. ```Shell flutter create . ``` -------------------------------- ### Migrate Custom BeamLocation from Beamer 0.14 to 1.X Source: https://github.com/slovnicki/beamer/blob/master/package/README.md Illustrates the required changes for custom `BeamLocation` implementations when migrating from Beamer 0.14 to 1.X. This includes adding a generic type parameter (``) to `BeamLocation` and renaming `pathBlueprints` to `pathPatterns`. ```Dart class BooksLocation extends BeamLocation { @override List get pathBlueprints => ['/books/:bookId']; ... } ``` ```Dart class BooksLocation extends BeamLocation { @override List get pathPatterns => ['/books/:bookId']; ... } ``` -------------------------------- ### Extending BeamStack for Books Navigation Source: https://github.com/slovnicki/beamer/blob/master/package/README.md This Dart code demonstrates how to extend the abstract `BeamStack` class to handle navigation related to books. It defines `pathPatterns` for `/books/:bookId` and implements `buildPages` to construct a list of `BeamPage` objects based on the current `BeamState`, including conditional pages for book details. ```dart class BooksStack extends BeamStack { @override List get pathPatterns => ['/books/:bookId']; @override List buildPages(BuildContext context, BeamState state) { final pages = [ const BeamPage( key: ValueKey('home'), child: HomeScreen(), ), if (state.uri.pathSegments.contains('books')) const BeamPage( key: ValueKey('books'), child: BooksScreen(), ), ]; final String? bookIdParameter = state.pathParameters['bookId']; if (bookIdParameter != null) { final bookId = int.tryParse(bookIdParameter); pages.add( BeamPage( key: ValueKey('book-$bookIdParameter'), title: 'Book #$bookIdParameter', child: BookDetailsScreen(bookId: bookId), ), ); } return pages; } } ``` -------------------------------- ### Access Route Attributes from Beamer Context Source: https://github.com/slovnicki/beamer/blob/master/package/README.md Illustrates how to retrieve route-specific attributes, such as `bookId`, from the current `BeamState` within a Flutter `Widget`'s build method using `Beamer.of(context).currentBeamStack.state`. ```dart @override Widget build(BuildContext context) { final beamState = Beamer.of(context).currentBeamStack.state as BeamState; final bookId = beamState.pathParameters['bookId']; ... } ``` -------------------------------- ### Understanding Page Keys in Beamer Navigation Source: https://github.com/slovnicki/beamer/blob/master/package/README.md This section details the critical role of `BeamPage.key` in Beamer's navigation system. It explains how `Navigator` uses these keys to efficiently compare old and new page lists, optimizing rebuilds and preventing unexpected UI behavior when beaming to new routes. It emphasizes the necessity of setting a unique `ValueKey` for each `BeamPage` to ensure proper navigation and state management. ```APIDOC BeamPage.key: - Purpose: Allows `Navigator` to identify and compare pages during navigation transitions. - Behavior: - If keys of two compared pages are equal (or both `null`), `Navigator` treats them as the same page. - This prevents unnecessary rebuilds or replacements of pages. - Importance: - Always set a unique `BeamPage.key` (e.g., `ValueKey`). - Failure to set keys can lead to UI not updating after beaming, as `Navigator` might incorrectly assume the page is unchanged. ``` -------------------------------- ### Migrate SimpleLocationBuilder from Beamer 0.13 to 0.14 Source: https://github.com/slovnicki/beamer/blob/master/package/README.md Shows the updated signature for route builders within `SimpleLocationBuilder` when migrating from Beamer 0.13 to 0.14. The `state` parameter is now directly passed to the builder function, simplifying access to the current beam state. ```Dart locationBuilder: SimpleLocationBuilder( routes: { '/': (context) => MyWidget(), '/another': (context) { final state = context.currentBeamStack.state; return AnotherThatNeedsState(state); } } ) ``` ```Dart locationBuilder: SimpleLocationBuilder( routes: { '/': (context, state) => MyWidget(), '/another': (context, state) => AnotherThatNeedsState(state) } ) ``` -------------------------------- ### BeamerDelegate Attributes for Nested Navigation Source: https://github.com/slovnicki/beamer/blob/master/package/README.md This section documents key attributes of `BeamerDelegate` relevant for managing multiple `Beamer` instances in a widget tree, particularly for nested navigation scenarios. It explains how `initializeFromParent`, `updateFromParent`, and `updateParent` control the synchronization and behavior of child and parent `BeamerDelegate`s. ```APIDOC BeamerDelegate attributes: - initializeFromParent: bool (default: true) Description: Initializes the BeamStack of a child BeamerDelegate when its Beamer is built. If true, child uses parent's configuration; if false, child uses its initialPath. - updateFromParent: bool (default: true) Description: Sets up a listener that calls BeamerDelegate.update with parent's configuration whenever the parent updates. - updateParent: bool (default: true) Description: Allows child BeamerDelegate to update its parent BeamerDelegate, keeping beamingHistory in sync. Important for BeamerBackButtonDispatcher. ``` -------------------------------- ### Perform Upward Navigation (Pop) Source: https://github.com/slovnicki/beamer/blob/master/package/README.md This snippet demonstrates how to achieve upward navigation, which is equivalent to 'popping' a page from the current navigation stack. It utilizes Flutter's standard `Navigator.of(context).maybePop()` method, commonly triggered by the default `AppBar`'s `BackButton`. ```dart Navigator.of(context).maybePop(); ``` -------------------------------- ### Navigating with Custom BeamStack State Source: https://github.com/slovnicki/beamer/blob/master/package/README.md This Dart snippet shows how to programmatically navigate by updating a custom state object (`MyState`) associated with a `BeamStack`. It casts the current `BeamStack`'s state to `MyState` and directly modifies a property, triggering navigation. ```dart onTap: () { final state = context.currentBeamStack.state as MyState; state.selectedBookId = 3; }, ``` -------------------------------- ### Generate Flutter Project Files Source: https://github.com/slovnicki/beamer/blob/master/examples/deep_location/README.md This command initializes a new Flutter project in the current directory, creating all necessary project files and folders. It's typically run once when setting up a new Flutter application or after cloning a repository that lacks the standard Flutter project structure. ```Shell flutter create . ``` -------------------------------- ### Initialize Flutter Project Files Source: https://github.com/slovnicki/beamer/blob/master/examples/multiple_beamers/README.md This command uses the Flutter CLI to create all required project files and directories in the current location. It's a crucial first step for setting up a new Flutter development environment or preparing an existing repository. ```shell flutter create . ``` -------------------------------- ### Initialize Flutter Project Files Source: https://github.com/slovnicki/beamer/blob/master/examples/location_builders/README.md Execute this command within the project directory to generate all required Flutter project files, such as 'pubspec.yaml' and 'main.dart', if they are not already present or need regeneration. ```Shell flutter create . ``` -------------------------------- ### Guard Specific Routes and Redirect Unauthenticated Users Source: https://github.com/slovnicki/beamer/blob/master/website/assets/markdown/guards.md This `BeamGuard` example demonstrates how to protect a predefined set of routes, such as `/profile/*` and `/orders/*`, by redirecting unauthenticated users to the login page. Unlike the previous example, it does not use `guardNonMatching`, applying the check only to the specified `pathBlueprints`. ```dart BeamGuard( pathBlueprints: ['/profile/*', '/orders/*'], check: (context, location) => context.isUserAuthenticated(), beamToNamed: (origin, target) => '/login', ) ``` -------------------------------- ### JavaScript Service Worker Registration and Main App Loading Source: https://github.com/slovnicki/beamer/blob/master/website/web/index.html This JavaScript code snippet manages the lifecycle of a web service worker. It registers 'flutter_service_worker.js', checks for updates based on 'serviceWorkerVersion', and ensures the 'main.dart.js' application script is loaded. It includes logic to wait for service worker activation, handle new versions, and provides a timeout-based fallback to directly load the script if the service worker fails to activate within 4 seconds. ```javascript var serviceWorkerVersion = null; var scriptLoaded = false; function loadMainDartJs() { if (scriptLoaded) { return; } scriptLoaded = true; var scriptTag = document.createElement('script'); scriptTag.src = 'main.dart.js'; scriptTag.type = 'application/javascript'; document.body.append(scriptTag); } if ('serviceWorker' in navigator) { // Service workers are supported. Use them. window.addEventListener('load', function () { // Wait for registration to finish before dropping the