Skip to Content

Hybrid Routing

Hybrid routing synchronizes navigation between Flutter’s Navigator (or go_router) and WebF’s internal routing. This is essential for creating multi-route WebF apps.

This guide covers the Flutter integration side of routing. For WebF app developers using React/Vue, see the Routing Guide which covers the @openwebf/react-router API in detail.

Understanding WebFSubView

WebFSubView is the essential entry point for displaying sub-route pages in your WebF app. It works in conjunction with WebF’s routing frameworks (@openwebf/react-router, @openwebf/vue-router) to enable seamless navigation between routes.

Key Concepts

  • WebF apps define routes using <router-link> elements in your HTML/JSX
  • Flutter displays these routes using WebFSubView widget
  • Each route can have its own title and navigation bar styling
import 'package:go_router/go_router.dart'; import 'package:webf/webf.dart'; final router = GoRouter( routes: [ // Catch-all route for WebF app routes GoRoute( path: '/:webfPath(.*)', pageBuilder: (context, state) { final path = '/${state.pathParameters['webfPath']}'; final controller = WebFControllerManager.instance.getControllerSync('app')!; return MaterialPage( child: WebFSubView( path: path, controller: controller, onAppBarCreated: (title, routeLinkElement) => AppBar( title: Text(title), ), ), ); }, ), ], ); // Use in MaterialApp MaterialApp.router( routerConfig: router, )

Adaptive UI Styling (Material vs Cupertino)

WebFSubView supports platform-adaptive navigation bars:

GoRoute( path: '/:webfPath(.*)', pageBuilder: (context, state) { final path = '/${state.pathParameters['webfPath']}'; final controller = WebFControllerManager.instance.getControllerSync('app')!; // Check theme attribute from router-link element final routeElement = controller.view.getHybridRouterView(path); final theme = routeElement?.getAttribute('theme') ?? 'material'; if (theme == 'cupertino') { return CupertinoPage( child: WebFSubView( path: path, controller: controller, onAppBarCreated: (title, routeLinkElement) => CupertinoNavigationBar( middle: Text(title), ), ), ); } return MaterialPage( child: WebFSubView( path: path, controller: controller, onAppBarCreated: (title, routeLinkElement) => AppBar( title: Text(title), ), ), ); }, )

Complete Example with @openwebf/react-router

Flutter Side

// 1. Pre-render controller with your WebF app WebFControllerManager.instance.addWithPrerendering( name: 'app', createController: () => WebFController(), bundle: WebFBundle.fromUrl('https://myapp.com/'), ); // 2. Set up go_router with WebFSubView final router = GoRouter( routes: [ GoRoute( path: '/:webfPath(.*)', pageBuilder: (context, state) { final path = '/${state.pathParameters['webfPath']}'; final controller = WebFControllerManager.instance.getControllerSync('app')!; return MaterialPage( child: WebFSubView( path: path, controller: controller, onAppBarCreated: (title, routeLinkElement) => AppBar( title: Text(title), ), ), ); }, ), ], );

React Side

import { Routes, Route, WebFRouter } from '@openwebf/react-router'; function App() { return ( <div className="App"> <Routes> <Route path="/" title="Home" element={<HomePage />} /> <Route path="/profile" title="Profile" theme="cupertino" element={<ProfilePage />} /> <Route path="/settings" title="Settings" element={<SettingsPage />} /> <Route path="/network" title="Network Demo" element={<NetworkPage />} /> </Routes> </div> ); } function HomePage() { return ( <div> <h1>Home Page</h1> {/* Programmatic navigation using WebFRouter API */} <button onClick={() => WebFRouter.push('/profile')}> Go to Profile </button> <button onClick={() => WebFRouter.pushState({ from: 'home' }, '/settings')}> Go to Settings (with state) </button> </div> ); } function ProfilePage() { // Use navigation methods const goBack = () => WebFRouter.back(); const replaceRoute = () => WebFRouter.replace('/settings'); return ( <div> <h1>Profile</h1> <button onClick={goBack}>Back</button> <button onClick={replaceRoute}>Replace with Settings</button> </div> ); }

WebFRouter API Methods

The WebFRouter object provides programmatic navigation methods. For complete API documentation and examples, see the Routing Guide.

Quick reference:

// Basic navigation WebFRouter.push(path, state) // Navigate to route WebFRouter.replace(path, state) // Replace current route WebFRouter.back() // Go back WebFRouter.pushState(state, path) // HTML5-style pushState WebFRouter.replaceState(state, path) // HTML5-style replaceState

Key Features

  • <Routes> and <Route> components for defining app routes
  • title attribute sets the navigation bar title in Flutter
  • theme attribute controls Material vs Cupertino styling
  • WebFRouter provides programmatic navigation
  • WebFSubView on Flutter side displays the route content
  • Each route automatically gets its own navigation bar via onAppBarCreated

Sub-views: Custom Layouts per Route

Sub-views allow embedding Flutter widgets at specific routes within your WebF app.

Define Route-Specific Widgets

WebFControllerManager.instance.addWithPrerendering( name: 'app', createController: () => WebFController(), bundle: WebFBundle.fromUrl('https://myapp.com/'), routes: { '/profile': (controller) { // Return Flutter widget for this route return CustomScrollView( slivers: [ SliverAppBar( title: Text('Profile'), floating: true, ), SliverToBoxAdapter( child: WebFRouterView( controller: controller, path: '/profile', ), ), ], ); }, '/settings': (controller) { return ListView( children: [ ListTile( title: Text('Flutter Setting'), onTap: () {}, ), Container( height: 500, child: WebFRouterView( controller: controller, path: '/settings', ), ), ], ); }, }, );

Use Router View Widget

// Display WebF app for a specific route WebFRouterView( controller: controller, path: '/profile', ) // Or use with controller name WebFRouterView.fromControllerName( controllerName: 'app', path: '/profile', builder: (context, controller) { return Scaffold( appBar: AppBar(title: Text('Profile')), body: WebFRouterView( controller: controller, path: '/profile', ), ); }, )

Next Steps