Flutter

Router Guard

AuthyraGuard, AuthyraInverseGuard, AuthyraNavigationObserver, and AuthyraRouter for plain Navigator apps.
If you're on GoRouter, AutoRoute, Beamer, or any declarative router, use its own redirect mechanism wired to authStateChanges instead, that's the pattern used throughout the rest of these docs. The widgets on this page are specifically for apps on plain Navigator with named routes.

Authyra deliberately doesn't ship a GoRouter-specific guard; router diversity in the Flutter ecosystem (GoRouter, AutoRoute, Beamer, VRouter, Navigator 2.0) means one guard can't fit all of them well, and Authyra's job is the auth logic, not navigation. For Navigator-based apps, these four widgets cover the common cases.


AuthyraGuardConfig

Shared configuration for AuthyraGuard and AuthyraInverseGuard:

class AuthyraGuardConfig {
  final String? loginRoute;
  final Widget Function(BuildContext)? loginBuilder;
  final String? homeRoute;
  final Widget Function(BuildContext)? loadingBuilder;
  final bool allowOnError;
  final Future<bool> Function(AuthSession?)? customCheck;
}

Either loginRoute or loginBuilder is required. customCheck overrides the default "session exists and isn't expired" logic; allowOnError controls whether a thrown error during the check counts as authenticated (default false, denies).


AuthyraGuard

Wrap content that requires authentication:

AuthyraGuard(
  config: AuthyraGuardConfig(loginRoute: '/login'),
  child: const HomePage(),
)

Shows config.loadingBuilder (or a default spinner) while checking, then either child or navigates to loginRoute/loginBuilder.

AuthyraInverseGuard

The opposite: wrap a login/register page that shouldn't be reachable once signed in:

AuthyraInverseGuard(
  config: AuthyraGuardConfig(homeRoute: '/home'),
  child: const LoginPage(),
)

AuthyraNavigationObserver

Guards a named list of routes at the Navigator level instead of wrapping each page:

MaterialApp(
  navigatorObservers: [
    AuthyraNavigationObserver(
      loginRoute: '/login',
      protectedRoutes: ['/profile', '/settings', '/admin'],
    ),
  ],
)

Checks Authyra.instance.isAuthenticated (or your customAuthCheck) on every didPush into a protected route name, and redirects to loginRoute if it fails.

AuthyraRouter

A single top-level split, useful for the simplest apps that just need "logged in screen" vs "logged out screen":

MaterialApp(
  home: AuthyraRouter(
    authenticatedBuilder: (context) => const HomePage(),
    unauthenticatedBuilder: (context) => const LoginPage(),
    loadingBuilder: (context) => const SplashScreen(),
  ),
)

Listens to sessionStream internally and swaps builders reactively.


See also

Copyright © 2026