Automatic slideshow


I have an app running in my company that shows a kpi number in a screen.

I want to know if it is possible to make something like a carousel in bootstrap that every 5 seconds makes a transition and shows another kpi.

Hi @kiko249 could you share with us about the things you’ve already tried?

  • tried using slider with time module
    — got problems with reset to the beggining
    — got problems with duplicate widget api error

  • tried extra components switch pages
    — dont have the effect expected as it kinda flashes when switching page

  • tried other custom build components but none of them worked as expected.

I want to have something more powepoint-like transitions

Any suggestions??

Best solution i found so far is the elements module but so far i wasn’t able to implement an automatic change of elements:

import streamlit as st
from streamlit_elements import elements, mui, html, sync


def slideshow_swipeable(images):
    # Generate a session state key based on images.
    key = f"slideshow_swipeable_{str(images).encode().hex()}"

    # Initialize the default slideshow index.
    if key not in st.session_state:
        st.session_state[key] = 0

    # Get the current slideshow index.
    index = st.session_state[key]

    # Create a new elements frame.
    with elements(f"frame_{key}"):

        # Use mui.Stack to vertically display the slideshow and the pagination centered.
        with mui.Stack(spacing=2, alignItems="center"):

            # Create a swipeable view that updates st.session_state[key] thanks to sync().
            # It also sets the index so that changing the pagination (see below) will also
            # update the swipeable view.
            with mui.SwipeableViews(index=index, resistance=True, onChangeIndex=sync(key)):
                for image in images:
                    html.img(src=image, css={"width": "100%"})

            # Create a handler for mui.Pagination.
            def handle_change(event, value):
                # Pagination starts at 1, but our index starts at 0, explaining the '-1'.
                st.session_state[key] = value-1

            # Display the pagination.
            # As the index value can also be updated by the swipeable view, we explicitely
            # set the page value to index+1 (page value starts at 1).
            mui.Pagination(page=index+1, count=len(images), color="primary", onChange=handle_change)

if __name__ == '__main__':
    st.title("Streamlit Elements Slideshow")

    st.subheader("Swipeable slideshow")

If you want to have a simple slide show you can always use streamlit.components.v1 and pass your own html code. For example:


import streamlit as st
import streamlit.components.v1 as components

<!DOCTYPE html>
<meta name="viewport" content="width=device-width, initial-scale=1">
* {box-sizing: border-box;}
body {font-family: Verdana, sans-serif;}
.mySlides {display: none;}
img {vertical-align: middle;}

/* Slideshow container */
.slideshow-container {
  max-width: 1000px;
  position: relative;
  margin: auto;

/* Caption text */
.text {
  color: #f2f2f2;
  font-size: 15px;
  padding: 8px 12px;
  position: absolute;
  bottom: 8px;
  width: 100%;
  text-align: center;

/* Number text (1/3 etc) */
.numbertext {
  color: #f2f2f2;
  font-size: 12px;
  padding: 8px 12px;
  position: absolute;
  top: 0;

/* The dots/bullets/indicators */
.dot {
  height: 15px;
  width: 15px;
  margin: 0 2px;
  background-color: #bbb;
  border-radius: 50%;
  display: inline-block;
  transition: background-color 0.6s ease;

.active {
  background-color: #717171;

/* Fading animation */
.fade {
  animation-name: fade;
  animation-duration: 1.5s;

@keyframes fade {
  from {opacity: .4} 
  to {opacity: 1}

/* On smaller screens, decrease text size */
@media only screen and (max-width: 300px) {
  .text {font-size: 11px}

<h2>Automatic Slideshow</h2>
<p>Change image every 2 seconds:</p>

<div class="slideshow-container">

<div class="mySlides fade">
  <div class="numbertext">1 / 3</div>
  <img src="" style="width:100%">
  <div class="text">Caption Text</div>

<div class="mySlides fade">
  <div class="numbertext">2 / 3</div>
  <img src="" style="width:100%">
  <div class="text">Caption Two</div>

<div class="mySlides fade">
  <div class="numbertext">3 / 3</div>
  <img src="" style="width:100%">
  <div class="text">Caption Three</div>


<div style="text-align:center">
  <span class="dot"></span> 
  <span class="dot"></span> 
  <span class="dot"></span> 

let slideIndex = 0;

function showSlides() {
  let i;
  let slides = document.getElementsByClassName("mySlides");
  let dots = document.getElementsByClassName("dot");
  for (i = 0; i < slides.length; i++) {
    slides[i].style.display = "none";  
  if (slideIndex > slides.length) {slideIndex = 1}    
  for (i = 0; i < dots.length; i++) {
    dots[i].className = dots[i].className.replace(" active", "");
  slides[slideIndex-1].style.display = "block";  
  dots[slideIndex-1].className += " active";
  setTimeout(showSlides, 2000); // Change image every 2 seconds



1 Like

that works for me thank you!

1 Like

Hi @kiko249 I have implemented a component which should do exactly that. You can check it out here, hope this helps.

Hello Tomas

I tried your component but i’m getting executing the code posted on pypi
TypeError: unsupported operand type(s) for |: ‘type’ and ‘NoneType’

I’m running streamlit 1.23 and python 3.9

Hi Kiko,
Do you have a code snippet that I can try to reproduce your error?


I get the error running the code example provided in:

I think this had to do with a Python version compatibility issue. I have made a patch (i.e. version 0.0.4) which should solve the issue.
Could you please confirm?


Yes now it is working, good job
and thank you very much :slight_smile:

1 Like

Hey @kiko249 and @ThomasBouamoud,
Just wondering if mui.pagination works for images stored locally as well?
I mean to slideshow locally stored images in same format.

Hi @labhayl , the Carousel custom component does not currently support local images but I’m working on fixing this. It should be solved by the end of the week.

1 Like

Great Solution. Thanks for this.
Could you please help with following issues:

  1. I replaced the image path with “Images/myImage.png”. But the image is not displayed. The Images folder is there. And the file also exists.

  2. Dots are not displayed if used st.set_page_config(layout=“wide”)

Got it fixed here.


1 Like