New Component: Streamlit Navigation Bar

Streamlit Navigation Bar

Hi everyone!

I felt the need for a navigation bar for Streamlit apps and was not satisfied with the current solutions. So I created a component that allows anyone to place a navbar in their app. These are the guidelines I tried to follow:

  • Be simple to use
  • Look great out of the box
  • Apply custom styles
  • Integrate with Streamlit’s UI
  • Have a well-written documentation

It has some cool functionalities, like displaying an optional logo and external URLs. It also matches the active theme by default.

Below are some demos using the component. I hope people find it useful!


To install it, run:

pip install streamlit-navigation-bar

Basic example

Here is a basic code example and its output:

import streamlit as st
from streamlit_navigation_bar import st_navbar

page = st_navbar(["Home", "Documentation", "Examples", "Community", "About"])

Example 1
[App] [Source]

More examples

Below are two other examples. To avoid having a long post, you can see the code snippets that generated them in their [Source] or in the documentation in the GitHub repository.

An example with a sidebar and applying a custom style:

Example 2
[App] [Source]

An example using a logo, an external URL, multiple pages with content, among other things:

Example 3
[App] [Source]


You are welcome to help develop the Streamlit Navigation Bar! There are multiple ways to contribute, such as reporting a bug or requesting a feature. You can also just ask a question, if you want. To submit code for a pull request, make sure to read the guide on how to contribute.


Check the complete documentation (with parameters, requirements, roadmap and more) in the GitHub repository:


Hi @gabrieltempass

I agree that this is a super clean navigation bar and the logo is a great bonus.

Amazing job creating this, big kudos! :star::star:


Love it, perfectly blend with streamlit. :laughing:

1 Like

Amazing thank you for the effort!

1 Like


Hi @ferdy, thanks for the suggestion!

My intention was to create a space between the body of the app and the top of the window of 6rem. Because this is the default value used by Streamlit. But thanks to your comment, I noticed that the space from st_navbar was actually 7rem. So I released version 3.1.1 that fixes this and reduces to 6rem. Now this is the output:

And this is Streamlit’s default space (for comparison):

I also added a new feature to the component. It is an option that can be passed in the options parameter:

options = {
    "use_padding": True

When "use_padding" is set to True, which is the default, it will position the body at 6rem from the top (if the navbar has a default height). But when set to False, it will remove the space and place the body right below the navbar.

For those who want to use more or less space, I recommend combining this option with putting one or more st.write("") before the content of the body. Each write command with an empty string will add 1rem of space.


Great component. Request others should also try Hydralit Navbar - Custom Streamlit Component Responsive Navbar, which is already available for this purpose. Now we have two components to choose from. Thanks. :grinning:

Thank you for this component! I wonder why is my nav component showing up so low from the window top?

I’m just doing this:

        pages = ["Chatbot 🤖", "Chat with Documents 📖"]

        page = st_navbar(pages, selected=pages[default_id])

Hi @Odrec, thanks for your message!

Could you open a bug report about this?

It would help me reproduce the behavior you mentioned and understand why this is happening. Please, be sure to fill the “Debug info” section.

Once the bug report is opened, we can continue our conversation there, and spare this forum post from our eventual back-and-forth messages to resolve the issue.

1 Like

I figured what I was doing wrong. In my app I was initializing language and verifying cookies before loading the navbar and for some reason that was affecting its position. So now I do it after instantiating the navbar and now it’s on the right position.

1 Like

Can support for Sub Menu?

@tuanvuvo do you mean a navbar with a dropdown menu?

Kapture 2024-04-20 at 18.09.00

Like this bootstrap demo? If so, this feature is already on the roadmap. However, I can’t give you an estimated date for when this will be done. If this is not what you mean, please explain in more detail.


Sorry, deleted my post too soon.

I’ve tried to run the examples locally, but the navigation bar doesn’t render at all.
Any idea why this is happening? I’ve tried in Chrome, Edge and Firefox.
I’ve also tried to delete and recreate the venv without any success.

Hi @halfspring, could you please open a bug report about this?
Make sure to enter detailed steps to reproduce the problem and the software versions you are running.

1 Like

it’s amazing !!!

1 Like

Thank you very much for your wonderful component
I’ve already apply it to my personal project to replace streamlit-option-menu which can not automatically adapts to web page width for wide screen.
And I can not wait for your new navbar with a dropdown menu!

Just a simple question:
Is there some simple way to reduce the space between navbar and other streamlit widget just like the following picture?

1 Like

Hi @lifeofpi2012, I’m happy to hear that the component meets your needs!

Yes, you can remove this space, as explained in this other comment. Basically you just have to set the "use_padding" option to False. For example:

    pages=["Home", "Library", "Tutorials", "Development", "Download"],
    options={"use_padding": False}

It works and so simple!
Thank you very much for quick replay

1 Like

Hi everyone,

Just want to share a quick update about the component.

I released version 3.2.0, which features a new option called "hide_nav". It shows or hides (depending on its toggle state) the navigation widget that Streamlit creates for multipage apps. Here is an example:

True (default)

Other changes:


this might be a silly question, does this navbar work more like streamlit tabs (where all code is rendered regardless which tab you’re viewing) or the sidebar (where you’re only executing the sidebar choice you’re viewing)

1 Like