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

Intercepting routes do not work with redirect from next/navigation #54676

Closed
1 task done
acifani opened this issue Aug 28, 2023 · 10 comments
Closed
1 task done

Intercepting routes do not work with redirect from next/navigation #54676

acifani opened this issue Aug 28, 2023 · 10 comments
Labels
bug Issue was opened via the bug report template. locked Navigation Related to Next.js linking (e.g., <Link>) and navigation.

Comments

@acifani
Copy link
Contributor

acifani commented Aug 28, 2023

Verify canary release

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

Provide environment information

Operating System:
      Platform: darwin
      Arch: arm64
      Version: Darwin Kernel Version 22.6.0: Wed Jul  5 22:22:05 PDT 2023; root:xnu-8796.141.3~6/RELEASE_ARM64_T6000
    Binaries:
      Node: 18.12.0
      npm: 9.6.0
      Yarn: 1.22.19
      pnpm: N/A
    Relevant Packages:
      next: 13.4.20-canary.10
      eslint-config-next: N/A
      react: 18.2.0
      react-dom: 18.2.0
      typescript: 5.2.2
    Next.js Config:
      output: N/A

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

App Router, Routing (next/router, next/navigation, next/link)

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

https://github.com/acifani/intercepting-route-server-action/

To Reproduce

To reproduce the bug from my repo

  1. Go to https://intercepting-route-server-action.vercel.app/
  2. Insert a random string or number in With server/client redirect
  3. Click on Go

Generally

Have an intercepted page (see example structure from repro repo) and navigate to the route of that page using redirect from next/navigation.

The bug appears both on Vercel and locally.

Describe the Bug

This is the file structure in the repro project

app
├── @intercept
│   ├── (.)foo
│   │   └── [id]
│   │       └── page.tsx
│   └── default.tsx
├── foo
│   └── [id]
│       └── page.tsx
├── layout.tsx
└── page.tsx

Using router.push from useRouter works just as expected:

// working router.push
'use client'
import { useRouter } from 'next/navigation';

export function ClientUseRouter() {
  const router = useRouter();

  function onSubmit(e: FormEvent) {
    e.preventDefault();
    router.push(`/foo/${e.target[0].value}`);
  }

  return (
    <form action="" onSubmit={onSubmit}>
      <input type="text" name="id" placeholder="id" />
      <button>Go</button>
    </form>
  );
}

But using redirect from next/navigation does not work. A network call is made, but the page is not shown.
The bug appears both in client components or server components using Server Actions

// broken client redirect
'use client'
import { redirect } from 'next/navigation';

export function ClientRedirect() {
  function onSubmit(e: FormEvent) {
    e.preventDefault();
    redirect(`/foo/${e.target[0].value}`, 'push');
  }

  return (
    <form action="" onSubmit={onSubmit}>
      <input type="text" name="id" placeholder="id" />
      <button>Go</button>
    </form>
  );
}
// broken server redirect
import { redirect } from 'next/navigation';

async function navigate(data: FormData) {
  'use server';
  redirect(`/foo/${data.get('id')}`);
}

export function ServerRedirect() {
  return (
    <form action={navigate}>
      <input type="text" name="id" placeholder="id" />
      <button>Go</button>
    </form>
  );
}

Expected Behavior

The intercepted page should work the same way for router.push and redirect

Which browser are you using? (if relevant)

No response

How are you deploying your application? (if relevant)

No response

@acifani acifani added the bug Issue was opened via the bug report template. label Aug 28, 2023
@github-actions github-actions bot added the Navigation Related to Next.js linking (e.g., <Link>) and navigation. label Aug 28, 2023
@akomm
Copy link

akomm commented Aug 30, 2023

Think there is a bug with redirect not working if you use absolute url like /foobar and you have to use foobar. Can't find the issue again, but there is one.

@noccer
Copy link

noccer commented Sep 6, 2023

I'm having the same issue. It's my first time using redirect and it plain doesn't work for a simple thing like redirecting to /

@akomm
Copy link

akomm commented Sep 6, 2023

A bit upsetting: In the last cannary versions I don't see (at least in change list) any fixes. There is so much blocking breakage in routing and parallel routes, its scary. About to jump of on new projects from using next, were we already initiated and are in early phase of development. Lack of proper marking of experimental / alpha state code is something every dev should pay strong attention to. Going back to the stack used in previous projects that work well. I just hoped some layout and routing improvements that I've seen in nextjs13, but exactly that is very broken out of experimental phase.

@Diego-0110
Copy link

The documentation says (https://nextjs.org/docs/app/api-reference/functions/redirect):

Invoking the redirect() function throws a NEXT_REDIRECT error and terminates rendering of the route segment in which it was thrown.

In Server Components and Client Components, you should use redirect() only during its rendering (just like the example showed in the documentation). To do redirection in other situations you can use useRouter() (router.push()).

I would suggest to clarify this in the documentation, because the first time I read it I thought I could use redirect() just like router.push().

@yuxiaoy1
Copy link

Having the same issue, I'm using it in a server action function which handles a search input server component, It's annoying that it only succueed serveral times then the whole page goes to no responding.
Please fix the behavior.

@Diego-0110
Copy link

Having the same issue, I'm using it in a server action function which handles a search input server component, It's annoying that it only succueed serveral times then the whole page goes to no responding. Please fix the behavior.

In the situation you are using redirect it should work, since the documentation shows a similar example. But, note that Server Actions are experimental, so I wouldn't expect it to work as they should be.

Test

I've tried to replicate the issue with a basic test in Next 13.5.4 and redirect works fine.

File structure:

app
├── blog
│   └── page.js
├── actions.js
├── ClientComponent.jsx
├── layout.js
└── page.js

Code:

// app/page.js
import ClientComponent from "./ClientComponent";

export default function Home() {
  return (
    <main>
      <ClientComponent />
    </main>
  )
}
// app/ClientComponent.jsx
'use client'
 
import { myAction } from './actions'
 
export default function ClientComponent() {
  return (
    <form action={myAction}>
      <button type="submit">Add to Cart</button>
    </form>
  )
}
// app/actions.js
'use server'

import { redirect } from "next/navigation"

export async function myAction() {
  console.log('Server Action')
  redirect('/blog')
}
// app/blog/page.js
"use client"
import { useState } from "react"

export default function Home() {
  const [counter, setCounter] = useState(0)
  return (
    <main>
      <h1>Blog</h1>
      <h3>{counter}</h3>
      <button type="button" onClick={() => setCounter(counter + 1)}>+</button>
    </main>
  )
}

@yuxiaoy1
Copy link

@Diego-0110 It only suscceed serveral times, when I make some other operations and then trigger it,it would fali and the whole page goes to no responding.

@sinafath

This comment has been minimized.

@leerob
Copy link
Member

leerob commented Dec 30, 2023

Thank you for creating a reproduction. I just took a look here and have confirmed this is working as expected on canary based on my understanding. There's an opportunity to make this more clear in our docs, which I will do as well.

My understanding is that server-side redirects with redirect would not intercept the route, but instead, navigate directly to the "regular" page as you've deceived. To intercept, you would use next/link or router.push.

Secondly, redirect is supported for use in Client Components, but not in event handlers. It can be called from a Server Actions, which is imported (or passed as a prop) for usage in a form.

"use client";

import { navigate } from './actions';

export function ClientRedirect() {
  return (
    <form action={navigate}>
      <input type="text" name="id" placeholder="id" />
      <button>Go</button>
    </form>
  );
}
'use server';

import { redirect } from 'next/navigation';

export async function navigate(data: FormData) {
  redirect(`/foo/${data.get('id')}`);
}
CleanShot.2023-12-30.at.14.01.45.mp4

@leerob leerob closed this as completed Dec 30, 2023
leerob added a commit that referenced this issue Dec 31, 2023
agustints pushed a commit to agustints/next.js that referenced this issue Jan 6, 2024
Copy link
Contributor

This closed issue has been automatically locked because it had no new activity for 2 weeks. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jan 14, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Issue was opened via the bug report template. locked Navigation Related to Next.js linking (e.g., <Link>) and navigation.
Projects
None yet
Development

No branches or pull requests

7 participants