[▲ Vercel Community](/) · [Categories](/categories) · [Latest](/latest) · [Top](/top) · [Live](/live)

[Feedback](/c/feedback/8)

# Next.js router to open and close modal

340 views · 3 likes · 5 posts


r-sp (@r-sp) · 2025-02-13

I've tried using Parallel Routes to create a modal but am a bit confused on how to ignore the page from getting a new modal from the slot.

In this case, the color page has a lot of color harmonies that have links to other color pages and should not open a modal.

![priest.vercel.app|690x295](upload://Aj5xeq9XsMVvPbuGKeb9y4WfxV7.png)

### 1. Homepage
Color palettes based on hue.

### 2. Color Red Modal
Every time a user clicks on another link color, it changes the content inside the modal.

### 3. Color Red Page
On this page the modal or slot should be ignored.

### 4. Color Rose
It should open a color page without opening a modal.

### 5. Color Rose Modal
How does the slot not know that the page it is in is the current page?

### 6. Color Rose Image (API Response)
Attempt to open another page to clear the previous state.

### 7. Color Rose Page
The previous state is lost because `<Link />` has the `replace=true` prop, otherwise it would still be there but without the modal.

---

## Closing the Modal
Yes, we can close the modal by calling `router.back()`, what if we can close them using `router.push("/")` then redirect to homepage and close the modal.

### Why using `replace=true`?
In the image above you can see the arrow_back button to return to the previous state, and the hidden button as an overlay to close the modal. If I don't replace the page, the hidden button don't work like the arrow_back button. both call the same function.

```tsx
const router = useRouter();

const handleClose = () => {
  router.back();
};
```

## Using `router.push()` as alternative to close modal
This solution it will help edge cases that we don't know, such as using `<Link />` with `replace=true` and don't have previous state. See above image with number (3-4 and 5).

```tsx
const router = useRouter();

const handleClose = () => {
 if(typeof window !== "undefined"){
   if(window.history.length <= 1){
     router.push('/');
   } else {
     router.back();
   }
 }
};
```

## Add prop `modal=true` as optional to open modal
This solution should prevent opening modal within page for the same page. See above image with number (4 and 5).

```tsx
<Link href="/color/ff0080" modal={isModal ? true : false} {...} />
```

By adding `modal=false` prop the modal should be ignored and `<Link />` should behave as usual.

---

Sorry to the team reading this messy feedback, but I can't wait for this `<Link modal={isModal ? true : false} />`. Thank You!


r-sp (@r-sp) · 2025-02-13

Additional feedback about Metadata. Currently I'm writing a custom function that changes the homepage title to the current page title inside a modal.

```tsx
const title = `Color: ${currentColor}`;

useEffect(() => {
  // save homepage title
  const pageTitle = document.title;

  // set currentColor page title
  document.title = title;

  return () => {
    // set homepage title
    document.title = pageTitle;
  };
},[title]);
```

I wish I could use function [`generateMetadata()`](https://nextjs.org/docs/app/api-reference/functions/generate-metadata) inside `~/app/@portal/(.)color/page.tsx` or within modal.


r-sp (@r-sp) · 2025-02-15 · ♥ 1

I finally found a workaround, by pushing the link through the router when there is no history, then every time the modal changes to its new content, the page stays there.

```tsx
"use client";

import type { ComponentPropsWithoutRef } from "react";
import { useRouter } from "next/navigation";
import Link from "next/link";

interface Props extends Omit<ComponentPropsWithoutRef<"a">, "href" | "modal"> {
  href: string;
  modal: boolean;
}

export default function Porter({ href, modal, children, ...props }: Props) {
  const router = useRouter();
  return (
    <Link
      href={href}
      prefetch={false}
      replace={true}
      scroll={false}
      onClick={(e) => {
        if (!modal) {
          e.preventDefault();
          router.push(href);
        }
      }}
      {...props}
    >
      {children}
    </Link>
  );
}
```

By using this method we know if the current page has no history then any link with `replace=true` will be replaced with `replace=false` and the router saves the current page when the user tries to close the modal.


r-sp (@r-sp) · 2025-02-15 · ♥ 1

Yes, the link has been fixed but ignoring the modal in the current page is still an issue.

From the [docs](https://nextjs.org/docs/app/building-your-application/routing/parallel-routes#closing-the-modal): if navigating to any other page (such as `/foo` , `/foo/bar` , etc), you can use a catch-all slot

```tsx
export default function CatchAll() {
  return null
}
```
I guess this catch-all route is ignoring all the `params` not `searchParams`.


Pauline P. Narvas (@pawlean) · 2025-02-17 · ♥ 1

Thank you for coming back with the solution that worked for you!