Skip to content

What Is Streamlit Selectbox? How to Use st.selectbox

Updated on

A Streamlit selectbox lets the user choose one option from a dropdown list.

What a Streamlit selectbox means

If a Streamlit app needs the user to choose one environment, one model, one country, one chart type, or one workflow path, a selectbox is often the cleanest fit.

In plain terms, st.selectbox is Streamlit's single-choice dropdown widget. It keeps one current value selected, and that value becomes part of the app's state on every rerun.

Why st.selectbox matters

Selectboxes matter because many apps need to guide the user through one choice at a time without taking over too much screen space.

That makes them especially useful when:

  • the option list is moderately long
  • only one answer should be active
  • the page already has many widgets
  • the selected value should drive downstream logic

Compared with a long row of buttons or a visible radio list, a selectbox usually keeps the page calmer and easier to scan.

What st.selectbox is actually for

The practical question is not just "what does it do?" but "what problem does it solve?"

It solves the problem of choosing one value cleanly and reliably in a reactive app.

That usually means:

  • filtering a st.dataframe
  • switching between views in a dashboard
  • choosing a model size or deployment target
  • controlling a chart, table, or summary section
  • driving follow-up logic stored in st.session_state

After reading this guide, you should be able to:

  • create a selectbox with sensible defaults
  • allow an empty state when needed
  • format options without changing the underlying values
  • decide when st.selectbox is better than st.radio or st.multiselect

Common questions this guide answers

Many readers come to this topic with a very practical question already in mind.

This guide is mainly designed to answer questions like:

  • what can a selectbox actually do in a Streamlit app?
  • how is a selectbox different from a checkbox?
  • can a selectbox do multiple selection?
  • when should I switch to st.multiselect instead?

Quick Start

This first example shows the simplest use case: choosing one value from a short list.

import streamlit as st
 
contact_method = st.selectbox(
    "How should we contact you?",
    ["Email", "Phone", "SMS"],
)
 
st.write("Selected:", contact_method)

The return value is the selected option itself, not the index. That makes it easy to use directly in the rest of your app.

Core arguments you should know

ArgumentWhat it doesWhen to care
labelSets the field labelAlways
optionsDefines the available choicesAlways
indexChooses the default optionUse index=None for no default
placeholderShows hint text before selectionUseful with index=None
format_funcChanges how options are displayedGood for readable labels
accept_new_optionsLets users enter new valuesHelpful in semi-open workflows
keyGives the widget a stable identityNeeded when labels repeat
helpAdds extra guidanceHelpful for unfamiliar choices
on_changeRuns a callback after a changeUseful for app flow logic
disabledPrevents interactionGood for gated steps
label_visibilityShows or hides the labelUseful in compact layouts
widthControls rendered widthHelpful in dense forms or columns

Choose a default or allow no default

This is one of the most important design choices in a selectbox.

If the app should start with a valid choice already selected, use the default index behavior or set index explicitly.

import streamlit as st
 
region = st.selectbox(
    "Choose a region",
    ["APAC", "EMEA", "LATAM", "North America"],
    index=1,
)

If the user must make an explicit decision first, use index=None and a placeholder.

import streamlit as st
 
region = st.selectbox(
    "Choose a region",
    ["APAC", "EMEA", "LATAM", "North America"],
    index=None,
    placeholder="Select a region",
)

That pattern is often better for filters, forms, and setup flows because it avoids silently applying the first option.

Format labels without changing the real values

Sometimes the values you want to use in code are not the values you want to show to users.

This is what format_func is for.

import streamlit as st
 
env = st.selectbox(
    "Deployment target",
    ["dev", "staging", "prod"],
    format_func=lambda value: {
        "dev": "Development",
        "staging": "Staging",
        "prod": "Production",
    }[value],
)
 
st.write("Code value:", env)

The user sees friendly labels, but your code still receives the original values.

Let users enter new values when the workflow needs it

Modern Streamlit also supports accept_new_options=True, which is useful when the user may need to type a value that is not already in the list.

import streamlit as st
 
tag = st.selectbox(
    "Choose or create a tag",
    ["analytics", "finance", "ops"],
    index=None,
    placeholder="Select or type a tag",
    accept_new_options=True,
)
 
st.write("Current tag:", tag)

This is helpful in internal tools, metadata workflows, and lightweight admin apps where the option set is partly controlled but not fully fixed.

Use selectboxes with session state and callbacks

A selectbox already preserves its current value as part of widget state. When you add a key, that value also becomes available in st.session_state.

This example shows a selectbox driving a small app state update.

import streamlit as st
 
st.session_state.setdefault("selected_env", None)
 
def remember_env() -> None:
    st.session_state.selected_env = st.session_state.env
 
st.selectbox(
    "Environment",
    ["dev", "staging", "prod"],
    key="env",
    on_change=remember_env,
)
 
st.write("Saved environment:", st.session_state.selected_env)

This is a good pattern when one selection should update other parts of the page or advance a workflow.

Common st.selectbox patterns

Filter a dataset

Selectboxes are often the cleanest way to drive a simple one-value filter for a table or chart.

import pandas as pd
import streamlit as st
 
df = pd.DataFrame(
    {
        "team": ["A", "A", "B", "B"],
        "revenue": [120, 150, 90, 110],
    }
)
 
team = st.selectbox("Team", sorted(df["team"].unique()))
st.dataframe(df[df["team"] == team])

Choose a chart or output mode

This pattern is useful when one piece of data can be shown in multiple ways.

import streamlit as st
 
view = st.selectbox("View", ["Table", "Chart", "Summary"])
 
if view == "Table":
    st.write("Render the table here")
elif view == "Chart":
    st.write("Render the chart here")
else:
    st.write("Render the summary here")

Pair a selectbox with action buttons

If the choice should happen before a deliberate action, combine the selectbox with st.button instead of triggering heavy work immediately.

That pattern often feels better in apps that query APIs, run models, or update records.

st.selectbox vs other widgets

NeedBetter widget
Choose one option from a compact dropdownst.selectbox
Choose one option from a very short visible listst.radio
Choose multiple optionsst.multiselect
Trigger an actionst.button

The best widget is usually the one that matches the reader's mental model with the least explanation.

Selectbox vs checkbox vs multiselect

This comparison matters because readers often confuse these widgets before they use them in a real app.

Use a selectbox when:

  • the user should choose exactly one option
  • the choice list should stay compact

Use a checkbox when:

  • the user is turning one thing on or off
  • the value is fundamentally boolean

Use st.multiselect when:

  • the user should choose more than one option
  • the app needs a set of values, not a single value

If the reader is really asking, "Can a selectbox do multi-select?", the practical answer is no. That is the job of st.multiselect.

Layout notes

Selectboxes work especially well in forms, sidebars, and st.columns layouts because they preserve space.

If the choices are short and few, a radio button group may be more readable. If the list is longer or the layout is crowded, a selectbox is usually the better choice.

Troubleshooting

Why is the first option selected automatically?

That is the default behavior when you do not set index=None. If you want the user to choose explicitly, use index=None and placeholder.

How do I show a placeholder in a Streamlit selectbox?

Use index=None and pass a placeholder string.

Can users type a new value into st.selectbox?

Yes, if you set accept_new_options=True.

Why does my selectbox keep resetting?

The usual causes are changing the widget key, rebuilding the widget with different options every rerun, or resetting the related session state manually.

Related Guides

Frequently Asked Questions

What does st.selectbox do in simple terms?

It shows a dropdown and returns the single option the user selected.

How do I set a default value in Streamlit selectbox?

Use the index parameter to choose the default option by position.

How do I make a Streamlit selectbox start empty?

Set index=None and optionally add placeholder text.

Can st.selectbox return custom values?

It returns the selected option itself. You can keep code-friendly values and show user-friendly labels with format_func.

When should I use st.selectbox instead of st.radio?

Use st.selectbox when you want a compact single-choice control, especially if the option list is longer or space is limited.