Modals not dismissing on forward routing #50284
Replies: 24 comments 24 replies
-
Found a workaround I don't necessarily love: // AuthModal.tsx
import { usePathname } from 'next/navigation';
export function AuthModal({ children }: { children: ReactNode }) {
const pathname = usePathname();
if (!pathname.includes('auth')) {
return null;
}
// ...
} If anyone has a better way of handling preventing the intercepted Modal from remaining on screen after a |
Beta Was this translation helpful? Give feedback.
-
temp solution router.push("/dashboard", {
// TODO: remove this when [...catchAll] works
forceOptimisticNavigation: true,
}); |
Beta Was this translation helpful? Give feedback.
-
Have the same issue, modal doesn't dismiss when navigating to other page with [...catchAll] |
Beta Was this translation helpful? Give feedback.
-
Still having the same problem in next 13.4.19 |
Beta Was this translation helpful? Give feedback.
-
This was driving me crazy since I thought I did something wrong. Is it a bug that |
Beta Was this translation helpful? Give feedback.
-
The issue is that
The modal will now disappear when navigating to |
Beta Was this translation helpful? Give feedback.
-
Having the same issue in 13.5.3 |
Beta Was this translation helpful? Give feedback.
-
same issue.. nothing seems to work properly for me, using 13.5.6 version.. router.push("/dashboard", { this works well the first time i navigate to another route, but if I open the modal again and try going to another route(or the same) the modal does not close. |
Beta Was this translation helpful? Give feedback.
-
Unfortunately I ran into the same issue and spent way too much time thinking I'm doing something wrong. I followed the docs for parallel and intercepting routes to set up a basic modal and I cannot get it to dismiss with either a catchAll or router.push() Verified the behavior to be the same on Next 13.5.6 up to 14.0.2 canary. The official example linked in the docs - "Nextgram" - kinda works because it doesn't let you do anything once the modal is open and there are no other pages in the app, beside "photos". |
Beta Was this translation helpful? Give feedback.
-
This problem should be fixed with #58215 unless your catch-all is under a dynamic segment, then #58272 |
Beta Was this translation helpful? Give feedback.
-
My current solution to close all modals is using const segments = useSelectedLayoutSegment();
const backCount = segments == null ? 1 : segments.split('/').length + 1;
for (let i = 0; i < backCount; i++) {
router.back();
} |
Beta Was this translation helpful? Give feedback.
-
[...catchAll] still doesn't work. Version: 14.1.1 canary 36 |
Beta Was this translation helpful? Give feedback.
-
This is still not fixed in the latest canary ( Is there already an issue with a reproduction for this? For now I'm using this in my modal, which seems to work for my simple usecase: const pathname = usePathname();
const initialPath = useRef(pathname);
if(pathname !== initialPath.current) {
return null;
} |
Beta Was this translation helpful? Give feedback.
-
still not work in (14.1.4) const onSubmit = (values: z.infer<typeof GuestSchema>) => {
setError('')
startTransition(() => {
editGuest(values, id)
.then((data) => {
if (data?.error) {
setError(data.error)
}
if (data?.success) {
toast.success(data.success)
router.back()
}
})
})
} when success submitting the form, the Screen.Recording.2024-04-01.at.01.56.54.movbut when click the close button which have function <Button variant={'outline'} type='button' onClick={() => router.back()}>Close</Button> Screen.Recording.2024-04-01.at.01.58.49.movi have already tried to use const onSubmit = (values: z.infer<typeof GuestSchema>) => {
setError('')
startTransition(() => {
editGuest(values, id)
.then((data) => {
if (data?.error) {
setError(data.error)
}
if (data?.success) {
toast.success(data.success)
window.location.replace("/admin/guestlist")
}
})
})
} this is work but it will reset all the context Screen.Recording.2024-04-01.at.02.01.52.mov |
Beta Was this translation helpful? Give feedback.
-
i use this one
|
Beta Was this translation helpful? Give feedback.
-
Faced the same problem and wasted a lot of time. That's the main problem with Next JS - you don't realize when you're doing something wrong, and when it's just a bug and it doesn't work as it should Updated export const FixModalCloseBug = ({
expectedPath,
children,
}: {
expectedPath: string | RegExp;
children: ReactNode;
}) => {
const pathname = usePathname();
if (expectedPath instanceof RegExp) {
if (expectedPath.test(pathname)) {
return children;
}
return null;
} else if (pathname.includes(expectedPath)) {
return children;
}
return null;
}; Then simply: export default function Page({ params }: { params: any }) {
return (
<FixModalCloseBug expectedPath={"/subscription"}>
<SubscriptionModal params={params} />
</FixModalCloseBug>
);
} |
Beta Was this translation helpful? Give feedback.
-
I hope this might help, I didn't find any other good solution, "use client";
import { Sheet, SheetContent } from "@/components/ui/sheet";
import { usePathname, useRouter } from "@/lib/navigation";
import { type ReactNode, useEffect, useState } from "react";
export default function Modal({ children }: { children: ReactNode }) {
const [open, setOpen] = useState<boolean>(false);
const router = useRouter();
const pathname = usePathname();
const handleClose = (open: boolean) => {
if (!open) {
setOpen(false);
setTimeout(() => {
router.back();
}, 300);
}
};
useEffect(() => {
if (pathname === "/login" || pathname === "/cart") {
setOpen(true);
} else {
setOpen(false);
}
}, [pathname, setOpen]);
return (
<Sheet open={open} onOpenChange={handleClose}>
<SheetContent>
<div className="h-full w-full overflow-auto">{children}</div>
</SheetContent>
</Sheet>
);
} |
Beta Was this translation helpful? Give feedback.
-
This is my simple solution - check when the path changes using usePathname() and close it. The initialRender is to prevent it from closing immediately when the dialog opens. This solution works for Dialog, Drawer and Credenza. const pathname = usePathname()
const initialRender = useRef(true)
const [open, setOpen] = React.useState(false)
useEffect(() => {
if (initialRender.current) {
initialRender.current = false
} else {
setOpen(false)
}
}, [pathname])
return (
<Dialog open={open} onOpenChange={setOpen}>
<DialogContent>
<DialogHeader>
<DialogTitle>New Space</DialogTitle>
<DialogDescription>
Organise all your files and notes in one place.
</DialogDescription>
</DialogHeader>
<CreateSpaceForm teamId={teamId} />
</DialogContent>
</Dialog>
) |
Beta Was this translation helpful? Give feedback.
-
Still doesn't work in 14.2.4... |
Beta Was this translation helpful? Give feedback.
-
So, I found a solution that seems to indicate our issue here might be an edge case not working as expected, my modal was not closing, when my tree was like this (page as layout sibbling):
Now its working: |
Beta Was this translation helpful? Give feedback.
-
Any update on this? |
Beta Was this translation helpful? Give feedback.
-
still facing this issue in 14.2.4 |
Beta Was this translation helpful? Give feedback.
-
Same issue in 14.2.15 To add to this, if you have two modals in the same layout (ie. a login and register parallel & intercepted routes) if you link from one modal to the other route, BOTH modals will appear on the screen. I created a sandbox demonstrating this issue. |
Beta Was this translation helpful? Give feedback.
-
15.0.3 and same behaviour. |
Beta Was this translation helpful? Give feedback.
-
Following along with the examples given in the Parallel Routing docs, I have the following route structure:
Almost everything works beautifully.
✅ Clicking Login via
<Link href="/auth/login" />
on the homepage will pop open the login modal✅ Router will reflect
/auth/login
✅ Pressing refresh will render
/auth/login
as a page, as expected❌ Navigating via
router.push('/dashboard')
from within the modal does not close the modalThe docs seem to indicate this setup should work:
This doesn't appear to be working. Any help would be greatly appreciated!
Beta Was this translation helpful? Give feedback.
All reactions