Ax

AnimateX Pro

useToast

The useToast hook is a powerful utility for displaying toast notifications in your application. It provides an easy way to show temporary messages to users, such as success messages, error alerts, or informational prompts. Which works in hand with the Toast component.

Getting Started with the Toast & useToast

The Toast component and useToast utility could be added into your project either with the help of the command line or manually

Installation via Command Line

You can quickly add the Toast component and useToast utility to your project using the following steps and commands
Note: Make sure you have already installed animatex-pro into your project. If not, please refer to the Getting Started section first.
In your project directory run the following command. 🎈

What this does: Helps authenticate you. Giving you access to members only components

npx animatex-pro store <user-key>
Add the component into your project with the following command. 🎈
npx animatex-pro add toast

Adding the toast component manually

Manually setting up the toast component into your project add the following code snippets into your project.
Install Zustand with the following command.
npm i zustand
In your project directory create a utils folder.
Within the utils directory create a useToast.ts/js file.
Copy the following code and paste into your useToast.ts/js file.
NextjsReactjs
import { create } from "zustand"

//typeItem type
export type toastItem = {
    id?: string,
    message: string | React.ReactNode,
    type: "success" | "error" | "default" | string,
    isOpen?: boolean
}


//toast array type
interface toast{
    toast: Array<toastItem>,
    addToast: (toast: toastItem) => void,
    removeToast: (id: string) => void
}


const MAX_VALUE = 3


export const useToast = create<toast>((set => ({
    toast: [],

    //function to add toasts
    addToast: (toast:toastItem) => {
        const id = crypto.randomUUID()
        set((state) => {
            const updatedtoasts = [...state.toast]

            if(updatedtoasts.length >= MAX_VALUE){
                const oldest = updatedtoasts.find(t => t.isOpen)
                if(oldest){
                    oldest.isOpen = false
                    set((s) => ({
                        toast: s.toast.filter((tost) => tost.id !== oldest.id)
                    }))
                }}
            updatedtoasts.push({
                ...toast, id: id, isOpen: true
            })
            return { toast: updatedtoasts}
        }

    )

        //remove toast after some period of time (5s)
        setTimeout(() => {
            set((state) => ({
                toast: state.toast.map((t) => 
                    t.id === id ? {...t, isOpen: false} : t
                )
            }))

            set((state) => ({
                toast: state.toast.filter((t) => t.id !== id)
            }))

        }, 5000)
    },
    //remove toast function
    removeToast: (id: string) => set((state) => ({toast: state.toast.filter(t => t.id !== String(id)), isOpen: state.toast.length - 1 > 0}))
})))
In your component/ui directory create a toast.tsx/jsx file. Then copy the following code and paste into that file.
NextjsReactjs
"use client"
import { AnimatePresence, motion as m, Variants} from 'motion/react'
import { useToast } from '@/utils/useToast'
import { X } from 'lucide-react'
import { cn } from '@/lib/utils'

interface toastprops{
    position?: "tl" | "bc" | "bl" | "tr" | "tc" | "br",
    className?: string,
    stacked?: boolean 
}

export const Toast = ({position, 
  className, stacked=false}:toastprops) => {


  const { toast, removeToast } = useToast()  

  // defining the different positions
  const pos = position === "tl" ? " top-4 left-2" :
              position === "bc" ? "mx-auto bottom-4 left-0 right-0" :
              position === "bl" ? "bottom-4 left-2" :
              position === "tr" ? "top-4 right-2" :
              position === "tc" ? "mx-auto top-4 left-0 right-0" : "bottom-4 right-2"
  
  // defining style "error" and "success"
  const styles = {
    error: "border-red-300 dark:border-red-800",
    success: "border-green-300 dark:border-green-800",
  }

  // defining origin y & x directions for animations
  const ydirection = position?.split("")[0] === "t" ? -1 : 1
  const xdirection = position?.split("")[1] === "l" ? -1 : 1

  // stacking variant
  const toastVariants:Variants = {
        "hidden": {
            opacity: 0,
            y: (ydirection * 20),
            scale: 0.8
        },
        visible: (i) => ({
            opacity: 1,
            y: i === (toast.length - 1) ? 0 : ((toast.length - (i + 1)) * (ydirection * -15)),
            scale: i === (toast.length - 1) ? 1 : 1 - (toast.length - i) * 0.055
        }),
        "exit": {
          opacity: 0,
          scale: 0.85
        }
    }
  
    // flex-col layout toast arrangement variant
    const layoutVariant:Variants = {
       "hidden": {
            opacity: 0,
            x: (xdirection * 50)
        },
        visible: (i) => ({
            opacity: 1,
            x: 0,
            y: i === (toast.length - 1) ? 0 : `${((toast.length - (i + 1)) * (ydirection * -110))}%`,
        }),
        "exit": {
          opacity: 0,
          x: (xdirection * 50)
        }

    }


    const variant = stacked ? toastVariants : layoutVariant

  return (
    <>
      {/* Main variant component */}
      <AnimatePresence>
        {
          toast.map((t, i) => 
              t.isOpen &&
             <m.div key={t.id}
                style={{zIndex: 9999999}} 
                variants={variant}
                initial="hidden"
                animate="visible"
                exit={"exit"}
                custom={i}
                  className={cn('fixed w-80 p-2 rounded-md border-2 text-[14px] border-col bg-(--bg)',
                    pos, className,
                    t.type === "error" ? styles.error : t.type === "success" ? styles.success : ""
                  )}>
                  {t.message}
                  <X size={16}
                   onClick={() => removeToast(t.id ? t.id : "0")} 
                   className='absolute top-1 cursor-pointer opacity-40 right-1'/>
              </m.div>
          )
        }
      </AnimatePresence>
    </>
  )
}

And there you have successfully added the toast component into your project. ⚡

Using the Toast Component

Using the toast component is as easy as riding a bike :)
Import the toast component from your toast.tsx/jsxfile into your main page route. That's layout.tsx for Nextjs and App.jsx for Reactjs project. This makes the component accessible throughout your application.
import { Toast } from '@/components/ui/modals/toast'
const page = () => {
  return (
    <div>
      <Toast className="border-blue-400 dark:border-blue-600" stacked/>
    </div>
  )
}
export default page
Create an event to trigger the toast with the useToast hook.
PreviewCode

And Booom!🔥 You successfully setup toasts for your app.

© 2026

Built with ❤ by Newton