Not able to navigate back from dynamic route
Unanswered
Baltimore Oriole posted this in #help-forum
Baltimore OrioleOP
async/await is not yet supported in Client Components, only Server Components. This error is often caused by accidentally adding
getting this error while navigating to /profile from /proifile/id. It works fine If i remove revalidatePath from /profile/id component.
Need help.
'use client' to a module that was originally written for the servergetting this error while navigating to /profile from /proifile/id. It works fine If i remove revalidatePath from /profile/id component.
Need help.
37 Replies
Not sure if this is causing it but try removing that async modifier from the Page Component
The page component in which revalidatePath is being used
@Clown Not sure if this is causing it but try removing that async modifier from the Page Component
Baltimore OrioleOP
I tried this. didn't work.
@Baltimore Oriole I tried this. didn't work.
Send the complete error here then, with the stack trace
Baltimore OrioleOP
Uncaught Error: async/await is not yet supported in Client Components, only Server Components. This error is often caused by accidentally adding
at trackUsedThenable (react-dom.development.js:7778:39)
at useThenable (react-dom.development.js:10046:26)
at Object.use (react-dom.development.js:10064:28)
at use (react.development.js:1519:31)
at useUnwrapState (use-reducer-with-devtools.js:78:39)
at Router (app-router.js:203:73)
at renderWithHooks (react-dom.development.js:9745:28)
at updateFunctionComponent (react-dom.development.js:14159:32)
at beginWork$1 (react-dom.development.js:15948:32)
at HTMLUnknownElement.callCallback (react-dom.development.js:17629:30)
at Object.invokeGuardedCallbackImpl (react-dom.development.js:17667:30)
at invokeGuardedCallback (react-dom.development.js:17729:39)
at beginWork (react-dom.development.js:22805:21)
at performUnitOfWork (react-dom.development.js:21852:24)
at workLoopSync (react-dom.development.js:21617:17)
at renderRootSync (react-dom.development.js:21584:21)
at recoverFromConcurrentError (react-dom.development.js:20917:30)
at performConcurrentWorkOnRoot (react-dom.development.js:20871:46)
at workLoop (scheduler.development.js:200:48)
at flushWork (scheduler.development.js:178:28)
at MessagePort.performWorkUntilDeadline (scheduler.development.js:416:35)
'use client' to a module that was originally written for the server.at trackUsedThenable (react-dom.development.js:7778:39)
at useThenable (react-dom.development.js:10046:26)
at Object.use (react-dom.development.js:10064:28)
at use (react.development.js:1519:31)
at useUnwrapState (use-reducer-with-devtools.js:78:39)
at Router (app-router.js:203:73)
at renderWithHooks (react-dom.development.js:9745:28)
at updateFunctionComponent (react-dom.development.js:14159:32)
at beginWork$1 (react-dom.development.js:15948:32)
at HTMLUnknownElement.callCallback (react-dom.development.js:17629:30)
at Object.invokeGuardedCallbackImpl (react-dom.development.js:17667:30)
at invokeGuardedCallback (react-dom.development.js:17729:39)
at beginWork (react-dom.development.js:22805:21)
at performUnitOfWork (react-dom.development.js:21852:24)
at workLoopSync (react-dom.development.js:21617:17)
at renderRootSync (react-dom.development.js:21584:21)
at recoverFromConcurrentError (react-dom.development.js:20917:30)
at performConcurrentWorkOnRoot (react-dom.development.js:20871:46)
at workLoop (scheduler.development.js:200:48)
at flushWork (scheduler.development.js:178:28)
at MessagePort.performWorkUntilDeadline (scheduler.development.js:416:35)
have you tried to move the server action to another file ?
Baltimore OrioleOP
does that matter ?
what do your button and input components look like? sure there’s no async stuff written there?
@Dayo what do your button and input components look like? sure there’s no async stuff written there?
Baltimore OrioleOP
import * as React from "react";
import { Slot } from "@radix-ui/react-slot";
import { cva, type VariantProps } from "class-variance-authority";
import { cn } from "@/lib/utils";
const buttonVariants = cva(
"inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
{
variants: {
variant: {
default: "bg-primary text-primary-foreground hover:bg-primary/90",
destructive:
"bg-destructive text-destructive-foreground hover:bg-destructive/90",
outline:
"border border-input bg-background hover:bg-accent hover:text-accent-foreground",
secondary:
"bg-secondary text-secondary-foreground hover:bg-secondary/80",
ghost: "hover:bg-accent hover:text-accent-foreground",
link: "text-primary underline-offset-4 hover:underline",
},
size: {
default: "h-10 px-4 py-2",
sm: "h-8 rounded-md px-3",
lg: "h-11 rounded-md px-8",
icon: "h-10 w-10",
},
},
defaultVariants: {
variant: "default",
size: "default",
},
}
);
export interface ButtonProps
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
VariantProps<typeof buttonVariants> {
asChild?: boolean;
}
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
({ className, variant, size, asChild = false, ...props }, ref) => {
const Comp = asChild ? Slot : "button";
return (
<Comp
className={cn(buttonVariants({ variant, size, className }))}
ref={ref}
{...props}
/>
);
}
);
Button.displayName = "Button";
export { Button, buttonVariants };
The button and input components are ui components from shadcn ui.
import { Slot } from "@radix-ui/react-slot";
import { cva, type VariantProps } from "class-variance-authority";
import { cn } from "@/lib/utils";
const buttonVariants = cva(
"inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
{
variants: {
variant: {
default: "bg-primary text-primary-foreground hover:bg-primary/90",
destructive:
"bg-destructive text-destructive-foreground hover:bg-destructive/90",
outline:
"border border-input bg-background hover:bg-accent hover:text-accent-foreground",
secondary:
"bg-secondary text-secondary-foreground hover:bg-secondary/80",
ghost: "hover:bg-accent hover:text-accent-foreground",
link: "text-primary underline-offset-4 hover:underline",
},
size: {
default: "h-10 px-4 py-2",
sm: "h-8 rounded-md px-3",
lg: "h-11 rounded-md px-8",
icon: "h-10 w-10",
},
},
defaultVariants: {
variant: "default",
size: "default",
},
}
);
export interface ButtonProps
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
VariantProps<typeof buttonVariants> {
asChild?: boolean;
}
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
({ className, variant, size, asChild = false, ...props }, ref) => {
const Comp = asChild ? Slot : "button";
return (
<Comp
className={cn(buttonVariants({ variant, size, className }))}
ref={ref}
{...props}
/>
);
}
);
Button.displayName = "Button";
export { Button, buttonVariants };
The button and input components are ui components from shadcn ui.
alright. what about the components in the profile page?
Baltimore OrioleOP
import { db } from "@/server/db";
import { getServerSession } from "next-auth";
import { redirect } from "next/navigation";
import UserCommentCard from "./user-comment-card";
import { authOptions } from "@/server/auth";
import ProfileLinkCopyButton from "./profile-link-copy-button";
import Link from "next/link";
async function getDbUser(email: string | null | undefined) {
return await db.user.findFirst({
where: {
email,
},
});
}
async function getUserComments(email: string | null | undefined) {
if (email) {
const user = await getDbUser(email);
try {
const userComments = db.comment.findMany({
where: {
userId: user?.id,
},
});
return userComments;
} catch (e) {
console.log(e);
return [];
}
}
}
export default async function Page() {
const session = await getServerSession(authOptions);
if (!session) {
redirect("/api/auth/signin");
}
const user = await getDbUser(session?.user?.email);
const comments = await getUserComments(session?.user?.email);
return (
<div className="px-20 pt-10">
{/* <div className="flex items-center flex-row gap-5">
<h1 className="text-4xl text-ellipsis font-extrabold font">
Hey, {session?.user?.name}{" "}
</h1>
<ProfileLinkCopyButton
uri={https://localhost:8080/profile/${user?.id}`}/>
</div> /}
{/ <div>
<Link href={
/profile/${user?.id}}>put a comment</Link>{comments?.map((c) => (
<UserCommentCard key={c.id} comment={c?.comment} userId={c?.userId} />
))}
</div> */}
</div>
);
}`
@Dayo alright. what about the components in the profile page?
Baltimore OrioleOP
for now i have commented everything but still gettin the error
can i see your profile link copy button x user comment components
@Baltimore Oriole for now i have commented everything but still gettin the error
you commented everything where?
Baltimore OrioleOP
in the profile component
when exactly do you get the error?
you can see the profile page, yeah?
the error happens when you try to navigate from the profile page to the /id page
you can see the profile page, yeah?
the error happens when you try to navigate from the profile page to the /id page
Baltimore OrioleOP
no. m getting the error while navigation back from /id page to profile page
and how are you navigating back? click of a button? browser back?
let's do this. comment out the async get functions x their usage in your profile page. just return a p tag with hello world and try again
@Dayo let's do this. comment out the async get functions x their usage in your profile page. just return a p tag with hello world and try again
Baltimore OrioleOP
working fine in this case
good. so let's work our way up to isolate the issue
start by adding the session and rendering it
then retry
if it works add the getDbUser and finally the getUserComments
Baltimore OrioleOP
got the error for getDbUser
looks like your issue is with the db you're importing. what does that file look like?
Baltimore OrioleOP
import { PrismaClient } from '@prisma/client'
declare global {
// eslint-disable-next-line no-var
var cachedPrisma: PrismaClient
}
let prisma: PrismaClient
if (process.env.NODE_ENV === 'production') {
prisma = new PrismaClient()
} else {
if (!global.cachedPrisma) {
global.cachedPrisma = new PrismaClient()
}
prisma = global.cachedPrisma
}
export const db = prisma
declare global {
// eslint-disable-next-line no-var
var cachedPrisma: PrismaClient
}
let prisma: PrismaClient
if (process.env.NODE_ENV === 'production') {
prisma = new PrismaClient()
} else {
if (!global.cachedPrisma) {
global.cachedPrisma = new PrismaClient()
}
prisma = global.cachedPrisma
}
export const db = prisma
don't see anything wrong here.. did you add back the Profile link copy button?
if you did, try commenting it out and try again
Baltimore OrioleOP
no I didnt
I think it's a bug.
try inlining your get user db function within the page itself
sth like
const user = await db.user.findFirst...
sth like
const user = await db.user.findFirst...
Baltimore OrioleOP
Still the error is there
screenshot your current code
also, is your code on GitHub? if not can you make a repro repo on codesandbox so I can take a closer look?
@Dayo screenshot your current code
Baltimore OrioleOP
link to repo
https://github.com/abhizeit/social-animals/
https://github.com/abhizeit/social-animals/