Next.js Discord

Discord Forum

Using shadcn/ui sonner inside server action component

Answered
neon posted this in #help-forum
Open in Discord
I am not sure if I'm allowed to ask questions about shadcn/ui here, please inform me if I shouldn't, I'll delete this post immediately

This is my code:
import { Textarea } from "@/components/ui/textarea";
import { SendButton } from "./send-button";
import { Toaster } from "./ui/sonner";
import { toast } from "sonner";

export async function SendPage() {
  async function send(formData: FormData) {
    "use server";

    const message = formData.get("message");
    // ... some code (make POST request to an API)

    toast("Message sent!");
  }

  return (
    <div>
      ...
      <div>
        <form action={send}>
          <Textarea .../>
          <SendButton />
        </form>
      </div>
      <Toaster />
    </div>
  );
}

As you can see, I have a sonner() function call at the send of the server action (send). But it doesn't seem to work, it gives Error: (0 , sonner__WEBPACK_IMPORTED_MODULE_9__.toast) is not a function error. Are there any workarounds or tricks by which I can run sonner() function when the server action is completed?
Answered by Thrianta
Well regardless you can't use toast in a server component. I believe you will have to use a client component somewhere.

You could wrap the form action in a client form action. Similar to an onSubmit handler. I think this would work
"use client"
import {yourServerAction} from "./actions.ts"

<form action={async (formData) => {
    const res = await yourServerAction(formData)
    if (res.success) toast("success")
}}></form>
View full answer

12 Replies

@neon can i even use that in server components?
Knopper gall
no useTransition is for client components
you can await the action in server
(or chain .then)
I'm now really confused, are you calling a server action from a server component?
Thrianta
Well regardless you can't use toast in a server component. I believe you will have to use a client component somewhere.

You could wrap the form action in a client form action. Similar to an onSubmit handler. I think this would work
"use client"
import {yourServerAction} from "./actions.ts"

<form action={async (formData) => {
    const res = await yourServerAction(formData)
    if (res.success) toast("success")
}}></form>
Answer
@Knopper gall I'm now really confused, are you calling a server action from a server component?
I thought that's how I handle form submissions
Knopper gall
I mean yes, but as @Thrianta said you can't use toast in a server component