|
| 1 | +--- |
| 2 | +title: st.bottom |
| 3 | +slug: /develop/api-reference/layout/st.bottom |
| 4 | +description: st.bottom inserts a pinned container at the bottom of the app, perfect for chat inputs, toolbars, and persistent controls. |
| 5 | +keywords: st.bottom, bottom, pinned container, sticky footer, chat input, toolbar, persistent controls, streamlit bottom |
| 6 | +--- |
| 7 | + |
| 8 | +## st.bottom |
| 9 | + |
| 10 | +`st.bottom` is a layout container pinned to the bottom of the main app area. Use it for chat inputs, toolbars, footers, and other controls that should stay visible while users scroll through your app content. |
| 11 | + |
| 12 | +Elements can be passed to `st.bottom` using object notation and `with` notation. |
| 13 | + |
| 14 | +The following two snippets are equivalent: |
| 15 | + |
| 16 | +```python |
| 17 | +# Object notation |
| 18 | +st.bottom.[element_name] |
| 19 | +``` |
| 20 | + |
| 21 | +```python |
| 22 | +# "with" notation |
| 23 | +with st.bottom: |
| 24 | + st.[element_name] |
| 25 | +``` |
| 26 | + |
| 27 | +<Important> |
| 28 | + |
| 29 | +`st.bottom` is only available in the **main app area**. Using it inside [`st.sidebar`](/develop/api-reference/layout/st.sidebar), [`st.dialog`](/develop/api-reference/execution-flow/st.dialog), or event containers (such as [`st.toast`](/develop/api-reference/status/st.toast)) raises an error. |
| 30 | + |
| 31 | +</Important> |
| 32 | + |
| 33 | +## Keep chat input at the bottom |
| 34 | + |
| 35 | +[`st.chat_input`](/develop/api-reference/chat/st.chat_input) behaves differently depending on where you call it in your script. At the **base level** of your app (the main area, not inside another container), the chat input appears at the bottom of the app automatically. |
| 36 | + |
| 37 | +If you call `st.chat_input` **inside a container**, it renders **inline** in that container instead. For example, `st.expander("Settings").chat_input(...)` places the input inside the expander, not at the bottom of the viewport. |
| 38 | + |
| 39 | +Use `st.bottom` to force the chat input to the bottom in those cases: |
| 40 | + |
| 41 | +```python |
| 42 | +import streamlit as st |
| 43 | + |
| 44 | +tab_chat, tab_logs = st.tabs(["Chat", "Logs"]) |
| 45 | + |
| 46 | +with tab_chat: |
| 47 | + st.write("Chat history goes here.") |
| 48 | + st.bottom.chat_input("Ask a question") |
| 49 | + |
| 50 | +with tab_logs: |
| 51 | + st.write("Log output goes here.") |
| 52 | +``` |
| 53 | + |
| 54 | +## Add a sticky footer |
| 55 | + |
| 56 | +Use `st.bottom` for footers, toolbars, or status bars that should remain visible at the bottom of the viewport: |
| 57 | + |
| 58 | +```python |
| 59 | +import streamlit as st |
| 60 | + |
| 61 | +st.title("Dashboard") |
| 62 | +st.line_chart({"sales": [10, 20, 15, 30, 25]}) |
| 63 | + |
| 64 | +with st.bottom: |
| 65 | + st.caption("© 2026 My Company · All rights reserved") |
| 66 | +``` |
0 commit comments