How to get selected current hyperlink text in variable for next working

Dear Manager,

I have successfully implemented code to retrieve hyperlink data from Google. However, I am encountering a persistent issue: when I attempt to capture the text of a clicked hyperlink into a variable for subsequent processing, the system consistently returns the final hyperlink (labeled as “5Teshing”) regardless of which hyperlink I actually select. Whether I click on hyperlink 1, 2, 3, or 4, the variable always retrieves the text from hyperlink 5. Notably, when the data is exported to a download file, it correctly saves the currently selected hyperlink text. This discrepancy suggests the variable is not properly capturing the clicked hyperlink at the moment of interaction. I would greatly appreciate your review of my code and your assistance in resolving this issue so that the variable accurately returns the text of the hyperlink that was actually clicked.

Thank you in advance for your support.

import base64

import streamlit as st

if “textpara” not in st.session_state:

st.session_state.textpara = ''

def get_text_download_link(text_content, filename=“download.txt”, link_text=“Download File”):

"""

Generates an HTML anchor link string that embeds the text content 

as a base64 encoded data URI.

"""

\# 1. Encode text to bytes, then base64 bytes, then decode back to a string

b64_encoded = base64.b64encode(text_content.encode('utf-8')).decode('utf-8')

\# 2. Build the HTML string using the data URI scheme

href = f'<a href="data:text/plain;base64,{b64_encoded}" download="{filename}">{link_text}</a>'

st.session_state.textpara = link_text

return href

mfa = "Teshing "

mfa1 = “1Teshing”

mfa2 = “2Teshing”

mfa3 = “3Teshing”

mfa4 = “4Teshing”

mfa5 = “5Teshing”

# Example App Usage

text_data = “Hello World! This text will be saved into the downloaded file.”

# Generate the HTML link

download_link_html = get_text_download_link(mfa1, filename=“my_saved_text.txt”, link_text=mfa1)

st.markdown(download_link_html, unsafe_allow_html=True)

download_link_html = get_text_download_link(mfa2, filename=“my_saved_text.txt”, link_text=mfa2)

st.markdown(download_link_html, unsafe_allow_html=True)

download_link_html = get_text_download_link(mfa3, filename=“my_saved_text.txt”, link_text=mfa3)

st.markdown(download_link_html, unsafe_allow_html=True)

download_link_html = get_text_download_link(mfa4, filename=“my_saved_text.txt”, link_text=mfa4)

st.markdown(download_link_html, unsafe_allow_html=True)

download_link_html = get_text_download_link(mfa5, filename=“my_saved_text.txt”, link_text=mfa5)

# Render via Markdown with unsafe HTML allowed

st.markdown(download_link_html, unsafe_allow_html=True)

st.write(“=============================================================================================”)

# Using the ‘with’ notation (recommended)

with st.expander(“See explanation”):

st.write(“Here are the detailed notes or extra info.”)

st.write(st.session_state.textpara)

Welcome to the Streamlit community, and thanks for sharing your question and code! :tada: The issue is that your get_text_download_link function always sets st.session_state.textpara to the most recent link_text—which, after your loop, is always the last hyperlink (“5Teshing”). Clicking a hyperlink in Markdown/HTML does not trigger a Streamlit rerun or update session state; it just downloads the file. That’s why st.session_state.textpara doesn’t reflect which link was clicked—it only shows the last value assigned during script execution, not user interaction.

To capture which link was clicked and update a variable in Streamlit, you need to use Streamlit widgets (like st.button) with callbacks, not raw HTML links. Streamlit can’t detect clicks on HTML <a> tags for state updates. For clickable text that updates a variable, use buttons styled as links or Streamlit’s new “tertiary” button type for a text-like appearance. Here’s a minimal reproducible example:

import streamlit as st

if "textpara" not in st.session_state:
    st.session_state.textpara = ""

def set_textpara(text):
    st.session_state.textpara = text

labels = ["1Teshing", "2Teshing", "3Teshing", "4Teshing", "5Teshing"]
for label in labels:
    st.button(label, on_click=set_textpara, args=(label,), type="tertiary")

st.write("Selected:", st.session_state.textpara)

This way, clicking a button updates st.session_state.textpara with the correct label. If you want to combine this with a download, use st.download_button instead of a raw HTML link. For more details, see the Streamlit button design docs and download button docs.

Sources: