Flutter

Widgets

RequireAuth, RequireRole, AuthStateBuilder, AuthyraBuilder, and AuthyraScope.

authyra_flutter ships a handful of small, composable widgets. None of them are required, StreamBuilder on authStateChanges works everywhere too, see Reactivity →. These exist for the common cases.


AuthStateBuilder

Rebuilds whenever the session changes, the lowest-level of the bunch:

AuthStateBuilder(
  builder: (context, session) {
    if (session == null) return const Text('Please log in');
    return Text('Hello ${session.user.name}');
  },
)

Internally a thin StreamBuilder over Authyra.instance.sessionStream.


RequireAuth

Shows child only while a non-expired session exists:

RequireAuth(
  fallback: const Text('Sign in required'),
  child: ElevatedButton(
    onPressed: () => deleteAccount(),
    child: const Text('Delete account'),
  ),
)

fallback defaults to an empty SizedBox. Built on AuthStateBuilder, so it stays live as the session changes.

RequireRole

Same idea, gated on session.user.metadata['role']:

RequireRole(
  role: 'admin',
  fallback: const Text('Admins only'),
  child: const AdminPanel(),
)

Your AuthUser.metadata needs a 'role' key for this to match anything, populate it from your provider's signIn result (AuthUser(metadata: {'role': 'admin'})).


AuthyraScope and AuthyraBuilder

AuthyraScope is an InheritedWidget that makes an Authyra instance available to BuildContext extensions (context.activeSession, context.isAuthenticated) further down the tree:

MaterialApp(
  home: AuthyraScope(
    child: MyHomePage(),
  ),
)
final session = await context.activeSession;
final signedIn = context.isAuthenticated;

AuthyraBuilder uses that context extension to fetch the session with a loading flag:

AuthyraBuilder(
  builder: (context, session, isLoading) {
    if (isLoading) return const CircularProgressIndicator();
    if (session == null) return const LoginPage();
    return HomePage(user: session.user);
  },
)

AuthyraBuilder must be built under an AuthyraScope ancestor; AuthyraScope.of(context) throws StateError otherwise.

As currently implemented, AuthyraScope fetches the session once (on initState/didChangeDependencies), it does not yet subscribe to auth state changes and rebuild automatically when they happen. AuthyraBuilder re-fetches on its own dependency changes, which covers most practical cases, but if you need guaranteed live updates on every sign-in/sign-out, prefer AuthStateBuilder or a direct authStateChanges.listen() for that specific widget instead.
Copyright © 2026