TL;DR: If you're coming from Flet, think of FletX routing like Angular/Vue Router for pages. Instead of manually managing page.route and page.go(), you declaratively define routes and let FletX handle the page lifecycle.
Routing in FletX manages navigation between different pages in your application. Instead of manually showing and hiding controls, you define routes that map URL paths to page components. When a user navigates to a path, FletX automatically displays the corresponding page.
Flet provides basic navigation through page.route and page.go(), but this approach requires manual page management. FletX builds on top of Flet's navigation to provide:
Declarative route definitions: Define all routes in one place
Automatic page lifecycle: Components are created and destroyed automatically
Data passing: Send data between pages without global variables
Route parameters: Handle dynamic paths like /user/123
Protection: Guard sensitive routes with authentication checks
History management: Built-in back/forward navigation
fromfletximportFletXAppfromfletx.navigationimportrouter_config# Register the routerouter_config.add_routes([{"path":"/","component":HomePage}])# Run the appapp=FletXApp()app.run()
When the app starts, FletX navigates to / and displays your HomePage component.
How it works:
- path: The URL path to match (e.g., /, /about, /settings)
- component: The page class to display when the path matches
- FletX calls build() on your component to render the page
classProductDetailsPage(FletXPage):defbuild(self):# Access the data passed from the previous pageproduct_data=self.route_info.dataproduct_id=product_data.get("id")product_name=product_data.get("name")returnft.Column([ft.Text(f"Product: {product_name}"),ft.Text(f"ID: {product_id}")])
When to use data passing:
- Temporary data for a single navigation (like form data or selected item details)
- Data that doesn't need to persist across multiple page changes
classUserProfilePage(FletXPage):defbuild(self):# Get the user_id from the URLuser_id=self.route_info.params.get("user_id")returnft.Column([ft.Text(f"Viewing profile for user: {user_id}"),# Load user data based on user_id...])
# This will match /user/:user_id and set user_id to "123"navigate("/user/123")# This will match /user/:user_id and set user_id to "alice"navigate("/user/alice")
fromfletx.navigationimportRouteGuardclassAuthGuard(RouteGuard):def__init__(self,auth_service):self.auth_service=auth_serviceasyncdefcan_activate(self,route_info):# Return True to allow, False to blockreturnself.auth_service.is_logged_in()asyncdefcan_deactivate(self,route_info):# Optional: always allow leaving this routereturnTrueasyncdefredirect_to(self,route_info):# Where to redirect if blockedreturn"/login"
# Assume you have an auth_service instanceauth_service=AuthService()router_config.add_routes([{"path":"/login","component":LoginPage},{"path":"/dashboard","component":DashboardPage,"guards":[AuthGuard(auth_service)]# Protected route}])
Now if a user tries to access /dashboard without being logged in, they'll be redirected to /login.
# In your app setupcart_service=CartService()classProductPage(FletXPage):defbuild(self):defadd_to_cart():cart_service.add_item({"name":"Widget","price":10})returnft.ElevatedButton("Add to Cart",on_click=lambda_:add_to_cart())classCartPage(FletXPage):defbuild(self):items=cart_service.get_items()returnft.Column([ft.Text(f"Cart has {len(items)} items")])
Even though you navigate between pages, the cart_service maintains its state.
fromfletx.navigationimportModuleRouter# Create a module for admin routesadmin_module=ModuleRouter()admin_module.add_routes([{"path":"/","component":AdminHomePage},{"path":"/users","component":AdminUsersPage}])# Mount the module under /adminrouter_config.add_module_routes("/admin",admin_module)
This creates routes at /admin/ and /admin/users.
Decorator-based registration (similar to Angular):
fromfletx.navigationimportRouteMiddlewareclassLoggingMiddleware(RouteMiddleware):defbefore_navigation(self,from_route,to_route):print(f"Navigating from {from_route.path} to {to_route.path}")defafter_navigation(self,route_info):print(f"Arrived at {route_info.path}")router_config.add_route(path="/analytics",component=AnalyticsPage,middleware=[LoggingMiddleware()])
# GoodclassProductPage(FletXPage):defbuild(self):products=product_service.get_all()# Service handles logicreturnft.Column([...])# AvoidclassProductPage(FletXPage):defbuild(self):# Don't put database queries and business logic hereconnection=connect_to_db()products=connection.query("SELECT * FROM products")...