Creating Sanity navbar button plugin that opens modal instead of routing

3 replies
Last updated: Mar 1, 2021
🙋‍♀️ Is there a way (that isn’t too wild) to create a plugin that would be a button in the navbar that opens a modal on the current page instead of navigating to a new route for the tool? I made my way through
parts
->
DefaultLayout
->
Navbar
->
ToolMenu
and looks like ToolMenu will always route to its own page. There’s a div in the navbar code with
{/* Insert plugins here */}
as the content and that looks like it would be what I want, except I don’t know that it’s actually doing anything!
AI Update

Yes, there is a way to create a plugin with a button in the navbar that opens a modal without navigating to a new route! The Studio Components API allows you to customize various parts of the Studio UI, including the navbar.

According to the Studio Components Reference, you can override the navbar component to add custom elements. Here's how you can approach this:

Custom Navbar Button with Modal

You can use the studio.components.navbar configuration to render custom components alongside the default navbar:

// ./sanity.config.tsx
import {defineConfig, NavbarProps} from 'sanity'
import {Button, Dialog} from '@sanity/ui'
import {useState} from 'react'

function CustomNavbar(props: NavbarProps) {
  const [isOpen, setIsOpen] = useState(false)

  return (
    <>
      {props.renderDefault(props)} {/* Render the default navbar */}
      
      {/* Your custom button */}
      <Button
        onClick={() => setIsOpen(true)}
        text="Open Modal"
        tone="primary"
      />
      
      {/* Your modal */}
      {isOpen && (
        <Dialog
          header="My Custom Modal"
          id="custom-modal"
          onClose={() => setIsOpen(false)}
          width={1}
        >
          {/* Your modal content here */}
          <div>Modal content goes here!</div>
        </Dialog>
      )}
    </>
  )
}

export default defineConfig({
  // rest of config ...
  studio: {
    components: {
      navbar: CustomNavbar,
    }
  }
})

Key Points

  • renderDefault(props) renders the standard navbar, so you're extending rather than replacing it
  • You can add your custom button alongside the default navbar elements
  • Use Sanity UI components like Dialog, Button, etc. for consistency with the Studio's design
  • The modal/dialog stays on the current page - no routing needed

The {/* Insert plugins here */} comment you found in the source is likely a placeholder for future extension points, but the navbar component override is the official way to achieve what you're looking for. This approach gives you full control over adding interactive elements to the navbar without creating a separate tool route.

Show original thread
3 replies
Update: I ended up having the plugin use
_"implements"_: "part:@sanity/base/absolutes",
instead of
tool
, so it shows as a fixed button at the bottom right corner. Works for me 🤷‍♀️I really wish there were more documentation on the available parts, though! Or even links to where in the source code to find what exists. I spend a lot of time traversing through the folders of the Sanity source code in GitHub
😕
Totally see your frustration on the lack of documentation and insight into these things, User!
We're doing a push to replace much of our UI code with the new
@sanity/ui
library at the moment - once we get there we will start to refactor some of the data loading and UI pieces to make it easier for developers to use. Along with that process there will be proper documentation and more guides on how to do things. We're suuuper excited about getting to that point 😅
Apologies for the current situation - I'm impressed by your willingness to dive deep into the codebase
🕵️‍♀️ 🔍
Despite everything that hasn’t been documented yet, I think there’s still more existing documentation for Sanity than any other product I’ve come across!

Sanity – Build the way you think, not the way your CMS thinks

Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.

Was this answer helpful?