Dynamic Page Content Loading without a Multi-Page App

Summary

Dynamic Page Content Loading without a Multi-Page App

Without using a multi-page app…

My sidebar contains a dynamically generated menu. Each item is a link to a page that resides in a subfolder. (Example: /demo-pages/page.py) (Also see visual explanation at link below)

Originally, I had a multipage app, but needed a search box, where I could type and it would filter the page contents list. I now have that working great.

When I click a link, I need it’s code to load into the page, maintaining the sidebar. I looked into iframes, but couldn’t really see how to use session state variables to dynamically reload the iframe’s contents / src. It would load the initial page, but then it wouldn’t register a reload of the src when a link was clicked.

Tabs won’t work as each page to load is pretty much it’s own app. I know I could fiddle with session state, for maintaining where the sidebar search list was currently at based on user input. That would require placing the code on each sub page already created (a lot of them) and new users to adopt new code into their workflow.

I tried to see if there was a templating system where I could specify a placeholder “section” or “container” that the content would automatically load into, but couldn’t find anything.

I did a search of the forum and googled a lot, but for better or worse, didn’t come up with any answers, so I wanted to post here.

Visual Explanation

Link:
https://app-apps-zxxkvnjd9ufapp7wwq3kspi.streamlit.app/

Keywords/Phrases that I couldn’t find in the tags that may help future forum searches:

  • dynamic content loading
  • dynamic content rendering
  • dynamic iframe reloading
  • sidebar menu without multipage app

There are a few ways you might try and go about that. Is there a specific reason you don’t want to use a multipage app? The first way that comes to mind is something like this:

import streamlit as st


def page_1():
    st.write("Page 1")


def page_2():
    st.write("Page 2")


if st.sidebar.button("Page 1"):
    page_1()

if st.sidebar.button("Page 2"):
    page_2()