How to show a snackbar after a document action in Sanity?

10 replies
Last updated: Jan 12, 2021
Hi! Can someone help me showing a snackbar after a document action? I am trying everything and can't make it work
AI Update

I can help you with that! To show a toast/snackbar after a document action in Sanity Studio, you need to use the useToast hook from @sanity/ui.

Here's how to implement it in a custom document action:

import {useToast} from '@sanity/ui'

export function MyCustomAction(props) {
  const toast = useToast()

  return {
    label: 'My Action',
    onHandle: () => {
      // Your action logic here
      // ...
      
      // Show success toast
      toast.push({
        status: 'success',
        title: 'Success!',
        description: 'Your action completed successfully'
      })
      
      // Close the action dialog
      props.onComplete()
    }
  }
}

Important things to note:

  1. Import from the right package: Make sure you're importing useToast from @sanity/ui, not from another package
  2. Call it at the component level: The useToast() hook must be called inside your action component function, not inside the onHandle callback
  3. Toast status options: You can use 'success', 'warning', 'error', or 'info' for the status
  4. Optional properties: You can include title, description, duration, and closable properties

Here's a more complete example with error handling:

import {useToast} from '@sanity/ui'

export function MyCustomAction(props) {
  const toast = useToast()

  return {
    label: 'My Action',
    onHandle: async () => {
      try {
        // Your async action logic
        await someAsyncOperation()
        
        toast.push({
          status: 'success',
          title: 'Done!',
          description: 'Document updated successfully',
          duration: 3000 // milliseconds
        })
      } catch (error) {
        toast.push({
          status: 'error',
          title: 'Error',
          description: error.message
        })
      } finally {
        props.onComplete()
      }
    }
  }
}

You can see a real-world example in this custom document actions guide where they use useToast to show feedback after publishing Cloudinary assets.

If you're still having trouble, make sure your Studio is using a recent version of @sanity/ui (v1.0+) and that your document action is properly registered in your sanity.config.ts file. Let me know if you need help with the configuration part!

Show original thread
10 replies
Hi! How are you doing it now?
Hi
user H
the first thing i am trying to do is importing the Snackbar like this:

import Snackbar from "part:@sanity/components/snackbar/item";

After that, i have a button with a onclick function called handleSend, and i am returning this: (I am missing now some code sorry)


const handleSend = () => {
            
//generateCreativeWorks(value, document)
                        
return (
                
<Snackbar>
                    
This is my snackbar
                
</Snackbar>
            
)
        
}

Is this the way to go? Thank you!
I've tried inside a component (example above) and inside a documentAction, similar way 🙂
Hi
user H
any update on this? )
Have you tried giving the snackbar an id?
<Snackbar
        kind="error"
        key={Math.random()}
        title="Snackbar title"
        subtitle="testing"
      />
I will try with this and come back here and let you know!
Hi
user H
i try this solution but can't make it work 😞 i am not recieving any console errors or warnings
import PropTypes from 'prop-types'

import React from 'react'

import { FormBuilderInput, withDocument } from 'part:@sanity/form-builder'

import Button from 'part:@sanity/components/buttons/default'

import { generateCreativeWorks } from '../lib/cappture'

//import SnackbarItem from 'part:@sanity/components/snackbar/item'

import Snackbar from "part:@sanity/components/snackbar/item";


class GenerateCreativeWork extends React.Component {
    
static propTypes = {
        
type: PropTypes.shape({
            
title: PropTypes.string,
            
options: PropTypes.shape(),
        
}),
        
level: PropTypes.number,
        
focusPath: PropTypes.array,
        
onFocus: PropTypes.func,
        
onChange: PropTypes.func,
        
onBlur: PropTypes.func,
    
}

    
_inputElement = React.createRef()

    
focus() {
        
if (this._inputElement.current) {
            
this._inputElement.current.focus()
        
}
    
}

    
render() {
        
const {
            
document,
            
value,
            
level,
            
focusPath,
            
onFocus,
            
onBlur,
            
onChange,
        
} = this.props

        
const { inputComponent, ...type } = this.props.type

        
const handleSend = () => {
            
//console.log("SHOW SNACKBAR")
            
//generateCreativeWorks(value, document)
               
return (
                
<Snackbar
                
kind="error"
                
key={Math.random()}
                
title="Snackbar title"
                
subtitle="testing"
              
/>
            
)
                 
}

        
return (
            
<div>
                
<FormBuilderInput
                    
level={level}
                    
ref={this._inputElement}
                    
type={type}
                    
value={value}
                    
onChange={onChange}
                    
path={[]}
                    
focusPath={focusPath}
                    
onFocus={onFocus}
                    
onBlur={onBlur}
                
/>
                
<Button style={{ marginTop: 20 }} onClick={handleSend}>Link article(s) to this review</Button>
            
</div>
        
)
    
}

}


export default withDocument(GenerateCreativeWork)
Hi
user H
i've manage to solve this)For anyone with similar problems this worked for me:


<Snackbar
                    
id="snackbar"
                    
style={{ bottom: 75 }}
                    
kind={snackBarKind}
                    
key={Math.random()}
                    
title={snackbarMessage}
                    
subtitle={snackbarSubtitle}
                    
isOpen={snackBarOpen}
                    
isPersisted={true}
                    
isCloseable={true}
                    
offset={75}
                    
onClose={closeSnackbar}
                    
onSetHeight={() => { }}
                
/>
that’s great to hear, good job!

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?