I'm trying building modal using parallel routes in Next.js 13.4
.
It works when I'm on the homepage (/
) and open the modal (push to /login
).
But when I refresh the /login
page, instead of showing homepage with modal, it shows the 404
page with the modal:
This is my folder structure:
This is @overlays/login/page.tsx
:
'use client';
import {useRouter} from 'next/navigation';
import {Dialog} from '@mui/material';
export default function Page() {
const router = useRouter();
return (
<Dialog
open
onClose={router.back}
keepMounted
disablePortal
>
Hello
</Dialog>
);
}
Could you tell me how to render the home page (/
) when navigating directly on parallel route /login
?
In order to get rid of the 404
, you are probably missing @overlays/default.tsx
:
export default function Default() {
return null;
};
It's explained in the docs for Parallel Routes > Unmatched Routes:
Unmatched Routes
By default, the content rendered within a slot will match the current URL.
In the case of an unmatched slot, the content that Next.js renders differs based on the routing technique and folder structure.
[...]
Reload
On reload, Next.js will first try to render the unmatched slot's default.js file. If that's not available, a 404 gets rendered.
Based on your last question, it looks like you don't want the modal to be accessible as a standalone page, which is what the documentation seems to consider one of the main use cases for this:
Other examples could include opening a login modal in a top navbar while also having a dedicated
/login
page, or opening a shopping cart in a side modal.
If you want /login
to redirect to /
when directly accessed, your might want to use router interception to render a different component in that case, which can then just call redirect('/')
, so you should end up with the following files:
app
(home)
login
page.tsx <= LoginPage
@overlays
login
page.tsx <= LoginModal
page.tsx
And login/page.tsx
looks something like this:
import { redirect } from 'next/navigation'
export default function LoginPage() {
redirect('/')
return null;
};