Need help with the automatic scroll down to see the latest result of conversation

import streamlit as st
import pyperclip

Add custom CSS for styling

st.markdown(
“”"

.message-container {
display: flex;
align-items: center;
justify-content: flex-start;
margin-bottom: 10px;
}
.user-message {
background-color: #e0f7fa;
color: #00796b;
padding: 10px;
border-radius: 10px;
max-width: 60%;
word-wrap: break-word;
}
.bot-message {
background-color: #fce4ec;
color: #ad1457;
padding: 10px;
border-radius: 10px;
max-width: 60%;
word-wrap: break-word;
}
.stContainer {
overflow-y: auto !important;
max-height: 500px !important;
}

“”",
unsafe_allow_html=True,
)

Initialize session state

if “messagelog” not in st.session_state:
st.session_state.messagelog =

Simulate messages (for demonstration purposes)

st.session_state.messagelog.append({“role”: “user”, “message”: “Hello, bot!”})
st.session_state.messagelog.append({“role”: “bot”, “message”: “Hello! How can I help you today?”})

Create conversation container

convo_con = st.container(border=True, height=500, key=“convo_con”)

Display messages

with convo_con:
for idx, message in enumerate(st.session_state.messagelog):
if message[“role”] == “user”:
st.markdown(
f"“”



{message[‘message’]}

user-icon

“”“,
unsafe_allow_html=True,
)
else:
bot_col, message_col = st.columns([1, 29])
with bot_col:
st.image(“images/ai.png”, width=40)
with message_col:
st.markdown(
f”“”

{message[‘message’]}

“”",
unsafe_allow_html=True,
)
marginbtn1, copy_button, retry_button, marginbtn2 = st.columns([4, 10, 90, 1])
with copy_button:
unique_copy_key = f’copy_{idx}’
if st.button(“Copy”, key=unique_copy_key):
pyperclip.copy(message[“message”])
with retry_button:
unique_retry_key = f’retry_{idx}’
if st.button(“Retry”, key=unique_retry_key):
st.rerun()

JavaScript for auto-scrolling

scroll_script = “”"

“”"
st.markdown(scroll_script, unsafe_allow_html=True)

Im running it automatically

For better functionality, you could use Streamlit’s native chat elements such as st.chat_message and st.chat_input.

okay i already used the st.chat.input, can i ask help , how to make the automatic scroll to bottom after the result of chat_message?

If the user is already at the bottom of the chat, it will automatically scroll to the bottom as new messages are generated. However, if the user has manually scrolled up, automatic scrolling won’t work. I have implemented custom Javascript in the example code provided below to address this issue.

import streamlit as st
from streamlit.components.v1 import html
import openai 
import os
import dotenv

dotenv.load_dotenv()
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
openai_client = openai.OpenAI(api_key=OPENAI_API_KEY)

# Initialize session state for chat messages
if 'chat_messages' not in st.session_state:
    st.session_state.chat_messages = []

# Render the chat messages
for message in st.session_state.chat_messages:
    with st.chat_message(message['role']):
        st.markdown(message['content'])

if prompt := st.chat_input("Type your message here..."):
    st.session_state.chat_messages.append({"role": "user", "content": prompt})

    with st.chat_message("user"):
        st.markdown(prompt)

    chat_complete = openai_client.chat.completions.create(
        messages=st.session_state.chat_messages,
        model="gpt-4o-mini",
    )
    response = chat_complete.choices[0].message.content
    st.session_state.chat_messages.append({"role": "assistant", "content": response})

    with st.chat_message("assistant"):
        st.markdown(response)
    
    # Trigger a scroll to bottom of the chat
    html(
        """
        <div id="div" />
        <script>
            // Scroll the div into view smoothly
            var div = document.getElementById('div');
            div.scrollIntoView({ behavior: 'smooth', block: 'end' });
        </script>
        """
    )

This causes there to be a big giant white box at the bottom which is wrapped in an iFrame. Is there a workaround for this?

Ensure that the div element is not styled.

    # Trigger a scroll to bottom of the chat
    html(
        """
        <div id="div" />
        <script>
            // Scroll the div into view smoothly
            var div = document.getElementById('div');
            div.scrollIntoView({ behavior: 'smooth', block: 'end' });
        </script>
        """
    )