Skip to content

๐Ÿ‘คย ย Avatar

Submitted by Lukas Masuch

Summary

Display a circular avatar image with optional label and caption.

Functions

avatar

Display a circular avatar image with optional label and caption.

This component renders a circular avatar image, commonly used for user profiles, contact lists, or any UI that needs to display a person or entity visually. Optionally displays a label and caption to the right of the image.

Parameters:

Name Type Description Default
image ImageLike

The image to display. Supports URLs (str), file paths (str or Path), PIL images, numpy arrays, or raw bytes/BytesIO.

required
label str | None

Optional primary text displayed to the right of the avatar. Typically used for names or titles.

None
caption str | None

Optional secondary text displayed below the label. Typically used for roles, status, or descriptions.

None
height int

Avatar height (and width) in pixels. Defaults to 48.

48
width Literal['stretch', 'content'] | int

Component width. "content" (default) sizes to fit the content. "stretch" fills the container width. An integer sets a fixed pixel width.

'content'
border bool

If True, adds a subtle border around the avatar image. Defaults to False.

False
on_click Literal['ignore', 'rerun'] | Callable[[], None]

Click behavior. "ignore" (default) disables click interactions. "rerun" triggers an app rerun when clicked. Pass a callable to execute a custom callback when clicked.

'ignore'
key str | None

Unique key for this component instance. Required when using multiple avatars with the same parameters.

None

Returns:

Type Description
bool

True if the avatar was clicked on this run (when on_click != "ignore"),

bool

False otherwise. Always returns False when on_click is "ignore".

Raises:

Type Description
StreamlitAPIException

If height is less than 1 or on_click has an invalid value.

Example

Simple avatar:

avatar("https://avatars.githubusercontent.com/u/12345")

Avatar with label and caption:

avatar(
    "https://avatars.githubusercontent.com/u/12345",
    label="John Doe",
    caption="Software Engineer",
)

Clickable avatar:

if avatar(
    "profile.jpg",
    label="Jane Smith",
    on_click="rerun",
):
    st.write("Profile clicked!")
Source code in src/streamlit_extras/avatar/__init__.py
@extra
def avatar(
    image: ImageLike,
    *,
    label: str | None = None,
    caption: str | None = None,
    height: int = 48,
    width: Literal["stretch", "content"] | int = "content",
    border: bool = False,
    on_click: Literal["ignore", "rerun"] | Callable[[], None] = "ignore",
    key: str | None = None,
) -> bool:
    """Display a circular avatar image with optional label and caption.

    This component renders a circular avatar image, commonly used for user profiles,
    contact lists, or any UI that needs to display a person or entity visually.
    Optionally displays a label and caption to the right of the image.

    Args:
        image: The image to display. Supports URLs (str), file paths (str or Path),
            PIL images, numpy arrays, or raw bytes/BytesIO.
        label: Optional primary text displayed to the right of the avatar.
            Typically used for names or titles.
        caption: Optional secondary text displayed below the label.
            Typically used for roles, status, or descriptions.
        height: Avatar height (and width) in pixels. Defaults to 48.
        width: Component width. "content" (default) sizes to fit the content.
            "stretch" fills the container width. An integer sets a fixed pixel width.
        border: If True, adds a subtle border around the avatar image.
            Defaults to False.
        on_click: Click behavior. "ignore" (default) disables click interactions.
            "rerun" triggers an app rerun when clicked. Pass a callable to execute
            a custom callback when clicked.
        key: Unique key for this component instance. Required when using multiple
            avatars with the same parameters.

    Returns:
        True if the avatar was clicked on this run (when on_click != "ignore"),
        False otherwise. Always returns False when on_click is "ignore".

    Raises:
        StreamlitAPIException: If height is less than 1 or on_click has an
            invalid value.

    Example:
        Simple avatar:

        ```python
        avatar("https://avatars.githubusercontent.com/u/12345")
        ```

        Avatar with label and caption:

        ```python
        avatar(
            "https://avatars.githubusercontent.com/u/12345",
            label="John Doe",
            caption="Software Engineer",
        )
        ```

        Clickable avatar:

        ```python
        if avatar(
            "profile.jpg",
            label="Jane Smith",
            on_click="rerun",
        ):
            st.write("Profile clicked!")
        ```
    """
    # Validate height
    if height < 1:
        raise StreamlitAPIException(f"Avatar height must be at least 1 pixel, got {height}.")

    # Validate width
    if isinstance(width, int) and width < 1:
        raise StreamlitAPIException(f"Avatar width must be at least 1 pixel, got {width}.")
    if not isinstance(width, int) and width not in ("stretch", "content"):
        raise StreamlitAPIException(f"width must be 'stretch', 'content', or an integer, got {width!r}.")

    # Validate on_click
    if not callable(on_click) and on_click not in ("ignore", "rerun"):
        raise StreamlitAPIException(f"on_click must be 'ignore', 'rerun', or a callable, got {on_click!r}.")

    # Convert image to URL
    image_url = _convert_image_to_url(image)

    # Determine if clickable
    clickable = on_click != "ignore"

    # Calculate component height based on avatar height
    # Avatar height + padding (0.25rem * 2 = 0.5rem โ‰ˆ 8px) + small buffer
    component_height = height + 10

    # Prepare callback for clickable avatars
    callback: Callable[[], None] | None = None
    if clickable:
        callback = on_click if callable(on_click) else lambda: None

    # Build component kwargs
    component_kwargs: dict[str, Any] = {
        "key": key,
        "data": {
            "image_url": image_url,
            "height": height,
            "width": width,
            "border": border,
            "label": label or "",
            "caption": caption or "",
            "clickable": clickable,
        },
        "height": component_height,
        "width": width,
    }

    if clickable:
        component_kwargs["on_clicked_change"] = callback

    # Render component
    result = _AVATAR_COMPONENT(**component_kwargs)

    # Triggers reset after each rerun, so result.clicked is True only when clicked
    return bool(result.clicked) if clickable else False

Import:

from streamlit_extras.avatar import avatar # (1)!
  1. You should add this to the top of your .py file ๐Ÿ› 

Examples

example

def example() -> None:
    """Example usage of the avatar component."""
    st.subheader("Basic avatars")

    col1, col2, col3 = st.columns(3)

    with col1:
        avatar(
            "https://avatars.githubusercontent.com/u/1673013?v=4",
            label="Adrien Treuille",
            caption="Co-founder",
        )

    with col2:
        avatar(
            "https://avatars.githubusercontent.com/u/690814?v=4",
            label="Thiago Teixeira",
            caption="Co-founder",
        )

    with col3:
        avatar(
            "https://avatars.githubusercontent.com/u/47222480?v=4",
            label="Amanda Kelly",
            caption="Co-founder",
        )

    st.subheader("Different heights")

    col1, col2, col3 = st.columns(3)

    with col1:
        avatar(
            "https://avatars.githubusercontent.com/u/1673013?v=4",
            height=32,
            label="Small (32px)",
        )

    with col2:
        avatar(
            "https://avatars.githubusercontent.com/u/1673013?v=4",
            height=48,
            label="Medium (48px)",
        )

    with col3:
        avatar(
            "https://avatars.githubusercontent.com/u/1673013?v=4",
            height=64,
            label="Large (64px)",
        )

    st.subheader("Clickable avatar")

    if avatar(
        "https://avatars.githubusercontent.com/u/1673013?v=4",
        label="Click me!",
        caption="I'm interactive",
        on_click="rerun",
        key="clickable_avatar",
    ):
        st.toast("Avatar clicked!")

    st.subheader("Avatar only (no text)")

    with st.container(horizontal=True):
        avatar("https://avatars.githubusercontent.com/u/1673013?v=4", height=40)
        avatar("https://avatars.githubusercontent.com/u/690814?v=4", height=40)
        avatar("https://avatars.githubusercontent.com/u/47222480?v=4", height=40)
        avatar("https://avatars.githubusercontent.com/u/12345", height=40)

    st.subheader("Avatars with border")

    with st.container(horizontal=True):
        avatar("https://avatars.githubusercontent.com/u/1673013?v=4", height=40, border=True)
        avatar("https://avatars.githubusercontent.com/u/690814?v=4", height=40, border=True)
        avatar("https://avatars.githubusercontent.com/u/47222480?v=4", height=40, border=True)
        avatar("https://avatars.githubusercontent.com/u/12345", height=40, border=True)