Welcome to the community, and thanks for your detailed question!
This is a common issue in Streamlit apps when trying to capture which hyperlink was clicked, especially if you’re generating links in a loop. Streamlit’s widgets (like buttons) only persist their state for a single rerun, and if you use a variable inside a loop, it often ends up referencing the last value due to Python’s late binding in closures.
To capture the clicked hyperlink correctly, you should use a unique key for each clickable element and store the result in st.session_state. Here’s a minimal reproducible example using buttons (since hyperlinks in st.markdown or st.write can’t trigger Python callbacks):
import streamlit as st
links = ["Link 1", "Link 2", "Link 3", "Link 4", "5Teshing"]
if "clicked_link" not in st.session_state:
st.session_state.clicked_link = None
for idx, link in enumerate(links):
if st.button(link, key=f"link_{idx}"):
st.session_state.clicked_link = link
if st.session_state.clicked_link:
st.write(f"You clicked: {st.session_state.clicked_link}")
This approach ensures the correct link text is captured when clicked. If you’re using actual HTML hyperlinks, note that Streamlit can’t natively capture clicks on them—only widgets like buttons can trigger Python code. For more advanced needs, consider a custom component or using query parameters as a workaround.
Sources: