Skip to content

Multipage navigation

Goal

Use Streamlit’s pages/ layout with StreamTree PageLink rows built from discovery helpers instead of hand-maintaining paths.

Install

streamtree.helpers.pages ships in the default install. Optional [pages] extra remains reserved for future pinned deps (Dependency strategy).

Full demo:

"""List Streamlit ``pages/*.py`` entries via ``streamtree.helpers.pages`` (0.5.0+).

Use :func:`streamtree.helpers.page_links` (0.8.0+) to turn discovery rows into :class:`PageLink`
widgets without a generator expression.

Run from the repository root (so ``examples/pages/`` sits next to this file):

    streamlit run examples/pages_helpers_demo.py
"""

from __future__ import annotations

from streamtree import component, render
from streamtree.elements import Markdown, Page, VStack
from streamtree.helpers import discover_pages, page_links


@component
def Body():
    entries = discover_pages(__file__)
    if not entries:
        return VStack(
            Markdown("Add scripts under **`examples/pages/`** to see `PageLink` targets here."),
        )
    return VStack(
        Markdown("**Pages** discovered next to this script:"),
        *page_links(entries),
    )


if __name__ == "__main__":
    render(Page(Body()))

Stub page script under examples/pages/:

"""Stub multipage file for ``pages_helpers_demo.py`` (Streamlit ``pages/`` layout)."""

import streamlit as st

st.title("About (demo page)")

Run the multipage demo from repo root:

streamlit run examples/pages_helpers_demo.py

CLI scaffold with pages

pip install "streamtree[cli]"
streamtree init ./myapp --with-pages --name "My app"

Generated app.py wires discover_pages + page_links into a sidebar shell (see streamtree.helpers.scaffold).

Advanced helpers

  • iter_page_entries, prefetch_page_sources — optional compile() warm-up without importing page modules (Performance).
  • page_links_sidebar_sections, multipage_sidebar_nav — sectioned sidebars for larger pages/ trees.

See also