FlowRouter Extra

repository·master·Indexed 41 days ago

https://github.com/veliovgroup/flow-router

An extended, high-performance routing API for Meteor.js compatible with React, Vue, Svelte, and Blaze. It provides a comprehensive set of routing methods, template helpers, and a structured hook execution order (including .guard(), .waitOn(), and .action()) for managing route guards and data loading. Supports Meteor >=1.4, including Meteor 3.4, and offers full TypeScript support.

Tokens
38.9K
Snippets
153
Records
169
Agent score
52%

What's inside FlowRouter Extra

  1. Overview of FlowRouter API methods

    master

    The FlowRouter API is categorized into several functional groups to help manage routing, data manipulation, and reactivity:

    • General Methods: Core routing operations like .go(), .route(), .group(), and .render(), as well as global .triggers.
    • Workarounds: Methods and options for specific edge cases, such as .refresh(), .reload(), .pathRegExp, and .decodeQueryParamsOnce.
    • Manipulation: Tools to interact with route and query parameters, including .getParam(), .getQueryParam(), .setParams(), and .setQueryParams().
    • URLs and Data: Methods for inspecting the current state and generating URLs, such as .url(), .path(), .current(), and .getRouteName().
    • Reactivity: Methods for responding to changes, specifically .watchPathChange() and .withReplaceState().
    • Add-on Development: The .onRouteRegister() method for developers building extensions.
    • Tweaking: Low-level control via .wait() and .initialize().
  2. Available FlowRouter template helpers

    master

    FlowRouter provides a suite of template helpers designed to work with Meteor templates to inspect the current routing state, check route activity, and generate URLs or parameters.

    Route Activity Helpers:

    • isActiveRoute: Checks if the current route matches a specific route name.
    • isActivePath: Checks if the current path matches a specific path.
    • isNotActiveRoute: Negation of isActiveRoute.
    • isNotActivePath: Negation of isActivePath.

    URL and Parameter Helpers:

    • pathFor: Generates a path for a given route name and parameters.
    • urlFor: Generates a full URL for a given route name and parameters.
    • param: Retrieves a specific route parameter.
    • queryParam: Retrieves a specific query string parameter.

    Route Metadata Helpers:

    • currentRouteName: Returns the name of the currently active route.
    • currentRouteOption: Retrieves a specific option from the currently active route.
  3. Overview of Flow Router Hooks execution order

    master

    Flow Router provides a sequence of hooks that execute during the routing lifecycle. Understanding the execution order is critical for managing route guards, data loading, and side effects. The hooks execute in the following order:

    1. .guard(): Used for permission and access control.
    2. .whileWaiting(): Executes while the router is waiting for data or resources.
    3. .waitOn(): Defines specific data or resources to wait for.
    4. .waitOnResources(): Defines specific resources to wait for.
    5. .endWaiting(): Executes once the waiting period is over.
    6. .data(): Provides data to the route.
    7. .onNoData(): Handles cases where no data is available.
    8. .triggersEnter(): Executes logic when entering the route.
    9. .action(): The primary logic/rendering hook for the route.
    10. .triggersExit(): Executes logic when leaving the route.
  4. Handle hash changes and fragment navigation

    master

    When using .go() to navigate to a different hash (fragment) within the same path and query parameters, FlowRouter does not re-run the route logic. Instead, it allows the browser to handle the navigation as a standard anchor change.

    To respond to these changes (e.g., for tab switching or scrolling to a specific element), you should listen to the browser's hashchange event.

    // Example: Scrolling to an element when the hash changes
    window.addEventListener('hashchange', () => {
      const tab = window.location.hash.slice(1);
      if (tab) {
        document.getElementById(tab)?.scrollIntoView();
      }
    });
    
    // Triggering a hash change via FlowRouter
    FlowRouter.go('/profile#security');
  5. Understand the differences between FlowRouter and Iron Router

    master

    FlowRouter is a minimalistic router focused on UI performance and decoupling routing from rendering. Unlike Iron Router, which handles routing, subscriptions, and layout management in one package, FlowRouter provides APIs for these functionalities so you can choose your own tools.

    Key differences:

    • Rendering: FlowRouter does not handle rendering. You should use a dedicated library like BlazeLayout for Blaze or meteor-react-layout for React. Rendering calls are made within the route's action.
    • Subscriptions: It is highly recommended to handle subscriptions in the template/component layer. While FlowRouter has a subscription registration mechanism, it does not wait for subscriptions to complete before moving to the view layer.
    • Reactive Content: FlowRouter limits reactive data sources to a single run (when first called) to prevent unpredictable re-runs caused by URL changes.
    • Data Context: FlowRouter does not provide a data context; data should be retrieved directly in the template or component layer.
  6. Configure Blaze templates with FlowRouter hooks

    master

    When using Blaze templates with ostrio:flow-router-extra, you can define templates using .html files and manage their lifecycle using standard Meteor Template callbacks.

    Common callbacks available for any template (including layouts) include:

    • onCreated()
    • onRendered()
    • onDestroyed()
    • helpers()
    • events()
    import { Template } from 'meteor/templating';
    import './layout.html';
    
    Template.layout.onCreated(function () { /* ... */ });
    Template.layout.onRendered(function () { /* ... */ });
    Template.layout.onDestroyed(function () { /* ... */ });
    Template.layout.helpers({ /* ... */ });
    Template.layout.events({ /* ... */ });
  7. Apply guards to route groups

    master

    When you define a guard on a FlowRouter.group, that guard is inherited by all nested groups and routes within it.

    Execution Order: Guards execute from the parent group down to the child groups, and finally to the specific route guard.

    const authenticated = FlowRouter.group({
      guard(context, redirect) {
        if (!Meteor.userId()) {
          redirect('/sign-in');
        }
      }
    });
    
    authenticated.route('/settings', {
      action() {}
    });
  8. Use Triggers to run code on route entry and exit

    master

    Triggers allow you to execute logic before entering a route (triggersEnter) or after exiting a route (triggersExit).

    Route-level Triggers

    Define triggersEnter and triggersExit arrays in the route options.

    Group-level Triggers

    Define triggers in the FlowRouter.group() configuration to apply them to all routes in that group.

    Global Triggers

    Register triggers globally using FlowRouter.triggers.enter() and FlowRouter.triggers.exit(). You can filter global triggers using only or except keys (but not both simultaneously).

    // Route-level
    FlowRouter.route('/home', {
      triggersEnter: [trackRouteEntry],
      action: function () {},
      triggersExit: [trackRouteClose]
    });
    
    // Global with filtering
    FlowRouter.triggers.enter([trackRouteEntry], {only: ["home"]});
    FlowRouter.triggers.exit([trackRouteExit], {except: ["home"]});
  9. Server-side routing limitations and recommendations

    master

    FlowRouter is a client-side router and does not support server-side routing. While subscriptions run on the server to support Fast Render, the routing logic itself is client-centric.

    For server-side routing (handling headers, cookies, and HTTP methods like GET or POST), it is recommended to use a dedicated server-side router such as meteorhacks:picker.

  10. Check active or inactive routes and paths with Template Helpers

    master

    FlowRouter Extra provides several helpers to check if the current route matches a specific path or route name. These helpers return a configurable string (defaulting to 'active' or 'disabled') or false.

    Available Helpers

    • isActivePath: Returns a string if the supplied path matches the current path.
    • isActiveRoute: Returns a string if the supplied route name matches the current route name.
    • isNotActivePath: Returns a string if the supplied path does NOT match the current path.
    • isNotActiveRoute: Returns a string if the supplied route name does NOT match the current route name.

    Arguments

    All these helpers accept the following arguments:

    • Data context (Optional): A String or Object containing name, path, or regex.
    • name (String): Only for isActiveRoute and isNotActiveRoute.
    • path (String): Only for isActivePath and isNotActivePath.
    • regex (String|RegExp): To match via regular expression.
    • class (String): To specify a custom CSS class to return instead of the default.

    Usage Examples

    {{!-- Path matching --}}
    <li class="{{isActivePath '/home' class='is-selected'}}">...</li>
    <li class="{{isActivePath regex='^\\/products' class='is-selected'}}">...</li>
    <li class="{{isNotActivePath '/home' class='is-disabled'}}">...</li>
    
    {{!-- Route name matching --}}
    <li class="{{isActiveRoute 'home' class='is-selected'}}">...</li>
    <li class="{{isActiveRoute regex='home|dashboard' class='is-selected'}}">...</li>
    <li class="{{isNotActiveRoute 'home' class='is-disabled'}}">...</li>
    
    {{!-- Conditional logic --}}
    {{#if isActivePath '/home'}}
      <span>Show only if '/home' is the current route's path</span>
    {{/if}}
    <li class="{{isActivePath '/home' class='is-selected'}}">...</li>
    <li class="{{isActiveRoute 'home' class='is-selected'}}">...</li>
  11. Create nested route groups

    master

    You can nest groups within other groups to create hierarchical routing structures. A nested group inherits the prefix and properties of its parent group and appends its own prefix to it.

    For example, a group with prefix /admin containing a nested group with prefix /super will result in routes starting with /admin/super.

    const adminRoutes = FlowRouter.group({
        prefix: '/admin',
        name: 'admin'
    });
    
    const superAdminRoutes = adminRoutes.group({
        prefix: '/super',
        name: 'superadmin'
    });
    
    // handling /admin/super/post
    superAdminRoutes.route('/post', {
        action() { /* ... */ }
    });
  12. FlowRouter Extra Hooks execution order

    master

    FlowRouter Extra provides several hooks that execute in a specific sequence during the routing lifecycle. Understanding this order is critical for managing data loading and transitions:

    1. .whileWaiting()
    2. .waitOn()
    3. .waitOnResources()
    4. .endWaiting()
    5. .data()
    6. .onNoData()
    7. .triggersEnter()
    8. .action()
    9. .triggersExit()