Decorator-based routing with automatic view stacking for Flet applications.
- π― Decorator-based routing - Clean, intuitive
@view()
decorator for route definitions - π Automatic view stacking - Navigate
/users/123/profile
and get a stack of 3 views - π State management - Built-in state classes with
StateView
integration - β‘ Async support - Handle async data loading with automatic loading indicators
- π¨ URL parameters - Extract parameters from routes like
/user/{id}
- π Zero configuration - Just replace
ft.run()
with auto-routing enabled
pip install flet-stack
pip install git+https://github.com/fasilwdr/flet-stack.git
pip install git+https://github.com/fasilwdr/flet-stack.git@v0.1.0
git clone https://github.com/fasilwdr/flet-stack.git
cd flet-stack
pip install .
import flet as ft
from flet_stack import view
# Define your routes with the @view decorator
@view("/")
def home_view(page):
return ft.Column([
ft.Text("Home Page", size=30),
ft.Button("Go to Profile", on_click=lambda _: page.go("/profile")),
])
@view("/profile")
def profile_view(page):
return ft.Column([
ft.Text("Profile Page", size=30),
ft.Button("Back", on_click=lambda _: page.go("/")),
])
# Run your app with auto-routing
def main(page: ft.Page):
page.title = "My Flet App"
page.go("/") # Navigate to home
ft.run(target=main)
That's it! The routing is automatically enabled.
Extract parameters from your routes:
@view("/user/{user_id}")
def user_view(page, user_id):
return ft.Column([
ft.Text(f"User Profile: {user_id}", size=30),
ft.Button("Back", on_click=lambda _: page.go("/")),
])
Use state classes to manage component state:
class CounterState:
def __init__(self):
self.count = 0
@view("/counter", state_class=CounterState)
def counter_view(state, page):
def increment(e):
state.count += 1
page.update()
return ft.Column([
ft.Text(f"Count: {state.count}", size=30),
ft.Button("Increment", on_click=increment),
])
Load data asynchronously before showing your view:
class UserState:
def __init__(self):
self.user_data = None
async def load_user_data(state, user_id):
# Simulate API call
await asyncio.sleep(1)
state.user_data = {"id": user_id, "name": f"User {user_id}"}
@view("/user/{user_id}", state_class=UserState, on_load=load_user_data)
def user_detail_view(state, page, user_id):
return ft.Column([
ft.Text(f"Name: {state.user_data['name']}", size=20),
ft.Text(f"ID: {state.user_data['id']}", size=16),
])
While loading, a progress indicator is automatically displayed.
Pass additional Flet view properties:
@view(
"/settings",
horizontal_alignment=ft.CrossAxisAlignment.CENTER,
vertical_alignment=ft.MainAxisAlignment.CENTER,
padding=20,
)
def settings_view(page):
return ft.Text("Settings", size=30)
Routes automatically create a navigation stack. Navigating to /users/123/profile
creates:
- View 1:
/users
- View 2:
/users/123
- View 3:
/users/123/profile
This enables natural back navigation in your app.
flet-stack patches ft.run()
to automatically enable routing when your app starts. It:
- Registers all
@view
decorated functions - Intercepts route changes
- Builds a view stack from the URL path
- Handles state management and async loading
- Renders your views with proper navigation support
Check the examples/
directory for more detailed examples:
basic_example.py
- Simple routing and navigationadvanced_example.py
- State management, async loading, and URL parameters
Contributions are welcome! Please feel free to submit a Pull Request.
This project is licensed under the MIT License - see the LICENSE file for details.
Built on top of the amazing Flet framework.
If you encounter any issues or have questions:
- Open an issue on GitHub
- Check the examples directory
- Read the Flet documentation