I’m working on a contact form in Next.js with server-side email functionality. The form submission is working correctly, and the email is sent successfully (verified via the network and console logs). However, the toast notification (using useToast
) doesn’t appear on either success or error. I’ve confirmed that the route and SendEmail
function work as expected, and I’ve correctly imported and initialized the useToast
hook.
Despite this, the toast doesn’t show after form submission. Here’s the relevant code snippet for the toast in the handleSubmit
function. I’m not sure what’s preventing the toast from triggering. Could there be something wrong with how I’m handling the toast state or the rendering process in the Next.js app?
"use client";
import { Input } from "@/components/ui/input";
import { Card, CardContent, CardFooter } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Textarea } from "@/components/ui/textarea";
import { SendEmail } from "@/components/send-email";
import { useToast } from "@/hooks/use-toast";
import { useRouter } from "next/navigation";
import { Send } from "lucide-react";
export default function ContactForm() {
const { toast } = useToast();
const router = useRouter();
const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
const formData = new FormData(e.currentTarget);
try {
const result = await SendEmail(formData);
if (result.success) {
toast({
title: "Message Sent",
description: "Your message has been sent successfully.",
});
router.push("/");
}
} catch (error) {
toast({
title: "Error",
description: "Failed to send the message. Please try again.",
variant: "destructive",
});
}
};
return (
<Card className="w-full max-w-2xl mx-auto shadow-lg">
<form onSubmit={handleSubmit}>
<CardContent className="space-y-2">
<div className="grid grid-cols-2 gap-1">
<div className="flex flex-col items-start space-y-1">
<Input
type="text"
id="name"
name="name"
required
placeholder="First and Last Name"
className="w-full"
/>
</div>
<div className="flex flex-col items-start space-y-1">
<Input
type="email"
id="email"
name="SenderEmail"
required
placeholder="Personal email"
className="w-full"
/>
</div>
</div>
<div className="flex flex-col items-start space-y-0">
<select
id="subject"
name="subject"
required
className="w-full h-10 px-3 py-2 text-sm rounded-md border border-input bg-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"
>
<option value="">Select a subject</option>
<option value="General">General Inquiry</option>
<option value="schedule">Schedule A Meeting</option>
<option value="others">Others</option>
</select>
</div>
<div className="flex flex-col items-start space-y-1">
<Textarea
id="message"
placeholder="Leave me a short message, feel free to drop your phone number if you prefer!"
name="message"
required
className="w-full min-h-[150px]"
/>
</div>
</CardContent>
<div className="flex justify-center items-center">
<CardFooter>
<Button type="submit" variant={"outline"} className="w-full">
<Send className="w-5 h-5 mr-2" />
Send Message
</Button>
</CardFooter>
</div>
</form>
</Card>
);
}
I expected the toast notification to appear when the form was submitted successfully or if an error occurred. I verified that the form submission works, and the SendEmail
function runs without issues. I also confirmed that the useToast
hook is correctly imported and initialized. Despite this, the toast notification never appears. I tried logging the success and error states, and the logic runs as expected, but the toast itself doesn’t show up on the page.
I expected a toast notification to appear either with a success message after the form submission or an error message if it failed, but nothing happens visually.
2
Answers
You should import
Toaster
from"@/components/ui/toaster"
:I can think of two reasons here.
Toaster
component at the root layout of the next js project.To confirm this, You can add a test button component to one of your page
Add this to one of your page, then check whether it works. If it is, then only cause we can think of may be
Using
setTimeout
try to give some delay to therouter.push("/")
so that toast notification can get some time to show up.Either of this should work for sure, if your implementation of toast using shadcn ui is correct.