The 'format_func' parameter renders differently depending on the widget

I don’t know whether this is an expected behavior or not, but it seems that the ‘format_func’ parameter (used to modify the text displayed as an option) behaves differently depending on the widget.
More precisely, it supports emojis and symbols when used in a st.pills, but not in a st.multiselect.

Here is a minimal reproducible example :

st.pills("Test", [10, 20, 30], format_func=lambda value: f"{value} :coffee:", default=20)
st.multiselect("Test", [10, 20, 30], format_func=lambda value: f"{value} :coffee:", default=20)

I’d like to know if this is a bug or not. Thank you.

Streamlit 1.41.0 / Python 3.13

I was able to reproduce and I think it’s a bug. Passing the actual emoji does work though.

st.pills(
    "Test",
    [10, 20, 30],
    format_func=lambda value: f"{value} :coffee:",
    default=20,
)

st.multiselect(
    "Does not render emojis correctly",
    [10, 20, 30],
    format_func=lambda value: f"{value} :coffee:",
    default=[10, 20, 30],
)

st.multiselect(
    "This works though",
    [10, 20, 30],
    format_func=lambda value: f"{value} ☕",
    default=[10, 20, 30],
)

I think it’s a bug because emoji shortcodes should work for all widgets:

Thank you for confirming.
Passing the actual emoji indeed works. However there doesn’t seem to be a workaround for Google’s Material Symbols.

I have the same (or another?) problem with st.markdown when using unsafe_allow_html=True :

st.markdown("anytext<p>:coffee:</p>", unsafe_allow_html=True)
→ emoji is rendered

st.markdown("<p>:coffee:</p>", unsafe_allow_html=True)
→ emoji is not rendered

Google’s Material Symbols are not rendered in anyway.

There is a PR open to fix this for Selectbox here: [WIP] Allow markdown in the options of `st.selectbox` and `st.multiselect` by jrieke · Pull Request #10086 · streamlit/streamlit · GitHub

The current open issue is here if you want to upvote it: