Router
Every file in app/ is a screen. Folders make nested routes, and _layout.py decides how the screens in a folder are shown.
Files become routes
| File | Route |
|---|---|
app/index.py | / |
app/settings.py | /settings |
app/details/[id].py | /details/42 (id = "42") |
app/docs/[...rest].py | /docs/a/b/c (rest = ["a", "b", "c"]) |
app/(tabs)/home.py | /home (the group name is not in the URL) |
app/_layout.py | wraps every screen in its folder |
app/+not-found.py | any URL that matches nothing |
Each route file sets default to its screen component.
Layouts
A layout wraps the screens in its folder. Use Stack for push navigation, Tabs for a tab bar, Drawer for a side menu, or Slot to render the child with no chrome.
app/_layout.py
from pyxpo.router import Stack
def Layout():
return Stack(
Stack.Screen(name="index", options={"title": "Home"}),
Stack.Screen(name="details/[id]", options={"title": "Details"}),
screen_options={"headerTintColor": "#3776ab"},
)
default = Layoutapp/(tabs)/_layout.py
from pyxpo.router import Tabs
def TabsLayout():
return Tabs(
Tabs.Screen(name="home", options={"title": "Home"}),
Tabs.Screen(name="profile", options={"title": "Profile"}),
)
default = TabsLayoutNavigating
python
from pyxpo import Button, View
from pyxpo.router import Link, router
def Home():
return View(
Link("Open settings", href="/settings"),
Button(title="Show item 7", onPress=lambda: router.push("/details/7")),
Button(title="Go back", onPress=router.back),
)| Call | What it does |
|---|---|
router.push(href) | Open a screen on top of the current one. |
router.navigate(href) | Go to a screen, reusing it if it is already open. |
router.replace(href) | Swap the current screen. |
router.back() | Go back one screen. |
router.dismiss(n), router.dismiss_all() | Close screens in the current stack. |
Redirect(href=...) | Render it to send the user somewhere else, for example to a sign-in screen. |
Router hooks
app/details/[id].py
from pyxpo import Text, View, useCallback
from pyxpo.router import useFocusEffect, useLocalSearchParams, usePathname
def Details():
params = useLocalSearchParams()
path = usePathname()
useFocusEffect(useCallback(lambda: print("focused", path), [path]))
return View(Text("Item ", params["id"]))
default = DetailsuseLocalSearchParams(): the params of this screen.useGlobalSearchParams(): the params of the focused URL.usePathname()anduseSegments(): the current URL.useRouter(),useNavigation(),useIsFocused(),useFocusEffect().
Deep links
Set scheme in your app config. A link like demo://details/7 then opens the matching route. For https links, add associated_domains on iOS and intent_filters on Android.
Themes
app/_layout.py
from pyxpo import useColorScheme
from pyxpo.router import DarkTheme, DefaultTheme, Stack, ThemeProvider
def Layout():
scheme = useColorScheme()
return ThemeProvider(Stack(), value=DarkTheme if scheme == "dark" else DefaultTheme)
default = Layout