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
WebFSubViewwidget - Each route can have its own title and navigation bar styling
Basic Setup with go_router (Recommended)
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 replaceStateKey Features
<Routes>and<Route>components for defining app routestitleattribute sets the navigation bar title in Flutterthemeattribute controls Material vs Cupertino stylingWebFRouterprovides programmatic navigationWebFSubViewon 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
- Advanced Topics - Performance monitoring, theming, caching
- Deployment - Deploy to app stores