Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

App Dir: Avoid intercepted route for hard navigated page #51648

Open
1 task done
schemburkar opened this issue Jun 22, 2023 · 17 comments
Open
1 task done

App Dir: Avoid intercepted route for hard navigated page #51648

schemburkar opened this issue Jun 22, 2023 · 17 comments
Labels
Parallel & Intercepting Routes Related to Parallel and/or Intercepting routes.

Comments

@schemburkar
Copy link
Contributor

Verify canary release

  • I verified that the issue exists in the latest Next.js canary release

Provide environment information

Operating System:
      Platform: linux
      Arch: x64
      Version: #22 SMP Tue Jan 10 18:39:00 UTC 2023
    Binaries:
      Node: 18.14.2
      npm: 9.5.0
      Yarn: 1.22.19
      pnpm: N/A
    Relevant packages:
      next: 13.4.7-canary.4
      eslint-config-next: 13.4.7
      react: 18.2.0
      react-dom: 18.2.0
      typescript: 5.0.4

Which area(s) of Next.js are affected? (leave empty if unsure)

App directory (appDir: true)

Link to the code that reproduces this issue or a replay of the bug

https://codesandbox.io/p/sandbox/dazzling-hooks-fz6pjv

To Reproduce

  1. Run the code sandbox
  2. Navigate to the search modal using the Search button
  3. Type a query
  4. Refresh the page, full search page should open
  5. Update the search query using input control
  6. The search modal should also show up, along with the page updated.

The search modal should not show up.

Describe the Bug

  1. The home page contains list of articles.
  2. There is a Search button that opens the intercepted /search route in a Modal
  3. On typing in the input, search is supposed to happen (not implemented), url is updated with query string. e.g. /search?q=food

All Good so far.

  1. Now when a User refreshes the page, the full search page appears. say for url /search?q=food
  2. On the page, if user tries to update the search query, the page is updated as well as opens the intercepted /search route in a Modal

Since the user is already on the full /search page, there should not be any requirement to again open the intercepted route

Expected Behavior

When updating the route with a new query string, the page should get updated and not show the intercepted route modal. As the page is already loaded and should not be again intercepted.

Which browser are you using? (if relevant)

No response

How are you deploying your application? (if relevant)

No response

@schemburkar schemburkar added the bug Issue was opened via the bug report template. label Jun 22, 2023
@schemburkar
Copy link
Contributor Author

Sample Gif of the repro bug

intercept route bug

@louisthomaspro
Copy link

I am facing the same issue.
Classic example is the shop product list with /product/[id] that opens a preview modal. When user click on "See full details" button in the modal, we want to show the original route (product page) to the user.

Proposition is to have a property bypassRouteInterception in <Link>. It preloads and redirect to the original product page.

<Link href={`/product/${id}`} bypassRouteInterception>See full details</Link>

The workaround is:

onClick={() => { window.location.reload(); }}

@schemburkar
Copy link
Contributor Author

@louisthomaspro The reload workaround works for your use case perfectly. For me, I'm already on the search page. To update the search results, the router.replace(newUrl) shows modal for me!

The page should be intercepted when user is on another route. Once they are on the actual page, there should not be requirement to intercept the same route anymore!!!

@Korusuke
Copy link

Proposition is to have a property bypassRouteInterception in <Link>. It preloads and redirect to the original product page.

<Link href={`/product/${id}`} bypassRouteInterception>See full details</Link>

Something like this would be really useful. For my use-case I want the modal to have a ...Read More button which would open the full page view

@sheldon-welinga
Copy link

Am facing the same issue. Looking forward to a fix for this

@lukepearce
Copy link

Any update on this? I'm using query strings for variant selection on a product page. The product page is being shown in a modal using intercepting routes. When the page is visited directly, selecting a variant causes the modal to be displayed.

@darwinva97
Copy link

Proposition is to have a property bypassRouteInterception in <Link>. It preloads and redirect to the original product page.

<Link href={`/product/${id}`} bypassRouteInterception>See full details</Link>

Something like this would be really useful. For my use-case I want the modal to have a ...Read More button which would open the full page view

I like that API. Any update?

@AlmedinShala
Copy link

Facing the same issue, any update on this. Preferably search params should not trigger the modal to open.

@tomjamesallen
Copy link

We need the same functionality. bypassRouteInterception feels like a clean API to me 👍
Our case is that we're using clerk for auth, and in some cases we want the clerk signin / signup components to appear in a modal, and other times not.

@sarowarhosen03
Copy link

anyone found any soludtion . please let me know

@balazsorban44 balazsorban44 added the Parallel & Intercepting Routes Related to Parallel and/or Intercepting routes. label Apr 19, 2024
@jvzaniolo
Copy link

@sarowarhosen03

anyone found any soludtion . please let me know

You could use a normal Anchor tag:

<a href=href={"/product/" + slug}>View more details</a>

@sarowarhosen03
Copy link

@sarowarhosen03

anyone found any soludtion . please let me know

You could use a normal Anchor tag:

<a href=href={"/product/" + slug}>View more details</a>

what if i need to do it with JavaScript i i can use window.location.replace but the main problem is both are making hard reload and broke the single page application experience

@vespertilian
Copy link
Contributor

@sarowarhosen03

I set it up so the root page triggers the modal. It's not an ideal workaround but at least you don't have the same view rendering on top of itself. I also had to pass in the route to go back to when the modal closes.

"use client";
import { usePathname, useRouter, useSearchParams } from "next/navigation";
import { useEffect } from "react";
export default function SearchStocksPage({
  searchParams: { query },
}: {
  searchParams: { query?: string };
}) {
  const pathname = usePathname();
  const router = useRouter();
  const searchParams = useSearchParams();
  let done = false;
  useEffect(() => {
    if (!done) {
      done = true;
      router.push(`${pathname}?${searchParams.toString()}`);
    }
  }, []);
}

@sarowarhosen03
Copy link

i think i got a solution by making a seperate utility function

"use server";
import { redirect } from "next/navigation";

export default async function redirectHard(uri) {
  redirect(uri);
}

then call it from your client component

@ryparker
Copy link
Contributor

ryparker commented Jul 8, 2024

Any workarounds for when url query params are updated (via JS nuqs & non-shallow param replacements)?

Currently the only workaround i've found is to redirect to another route.

  1. So if my modal opens under /searchy (app/@search/(.)searchy/page.tsx)
  2. A refresh will open the full page route of /searchy (app/searchy/page.tsx), which just redirects to /search.
  3. User then lands on the full page route for /search (app/search/page.tsx) and is able to non-shallow update the url query params.
// app/searchy/page.tsx
import { redirect, RedirectType } from 'next/navigation';

/**
 * There is a bug where updating url query params (non-shallow) causes the modal to appear on the full page route.
 * https://github.com/vercel/next.js/issues/51648
 *
 * So we open the modal under /searchy and the full page route for /searchy will soft redirect to /search.
 */
export default function Page(props: any): any {
  console.log('searchy page props', props);
  const params = new URLSearchParams(props.searchParams);
  const newPath = `/search?${params.toString()}`;
  redirect(newPath, RedirectType.replace);
}

Hacky

@sarowarhosen03
Copy link

Any workarounds for when url query params are updated (via JS nuqs & non-shallow param replacements)?

Currently the only workaround i've found is to redirect to another route.

  1. So if my modal opens under /searchy (app/@search/(.)searchy/page.tsx)
  2. A refresh will open the full page route of /searchy (app/searchy/page.tsx), which just redirects to /search.
  3. User then lands on the full page route for /search (app/search/page.tsx) and is able to non-shallow update the url query params.
// app/searchy/page.tsx
import { redirect, RedirectType } from 'next/navigation';

/**
 * There is a bug where updating url query params (non-shallow) causes the modal to appear on the full page route.
 * https://github.com/vercel/next.js/issues/51648
 *
 * So we open the modal under /searchy and the full page route for /searchy will soft redirect to /search.
 */
export default function Page(props: any): any {
  console.log('searchy page props', props);
  const params = new URLSearchParams(props.searchParams);
  const newPath = `/search?${params.toString()}`;
  redirect(newPath, RedirectType.replace);
}

Hacky

Any workarounds for when url query params are updated (via JS nuqs & non-shallow param replacements)?

Currently the only workaround i've found is to redirect to another route.

  1. So if my modal opens under /searchy (app/@search/(.)searchy/page.tsx)
  2. A refresh will open the full page route of /searchy (app/searchy/page.tsx), which just redirects to /search.
  3. User then lands on the full page route for /search (app/search/page.tsx) and is able to non-shallow update the url query params.
// app/searchy/page.tsx
import { redirect, RedirectType } from 'next/navigation';

/**
 * There is a bug where updating url query params (non-shallow) causes the modal to appear on the full page route.
 * https://github.com/vercel/next.js/issues/51648
 *
 * So we open the modal under /searchy and the full page route for /searchy will soft redirect to /search.
 */
export default function Page(props: any): any {
  console.log('searchy page props', props);
  const params = new URLSearchParams(props.searchParams);
  const newPath = `/search?${params.toString()}`;
  redirect(newPath, RedirectType.replace);
}

Hacky

Instead of doing this redirect from server using a server action might be a good option

@yutakobayashidev
Copy link

I hope that 73390 will be merged, but I’ve discovered a workaround to modify the rewrites in nextConfig.

https://www.reddit.com/r/nextjs/comments/174m3xf/comment/k4bhrp2/

@samcx samcx removed bug Issue was opened via the bug report template. area: app labels Jan 23, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Parallel & Intercepting Routes Related to Parallel and/or Intercepting routes.
Projects
None yet
Development

No branches or pull requests