Skip to content

Libraries relying on monkey patching router.push no longer work with 15.3 #78085

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

Open
wintercounter opened this issue Apr 12, 2025 · 1 comment
Labels
Linking and Navigating Related to Next.js linking (e.g., <Link>) and navigation.

Comments

@wintercounter
Copy link

Link to the code that reproduces this issue

https://github.com/wintercounter/next-router-push-repro

To Reproduce

  1. Monkey-patch router.push
  2. Navigating using Link no longer calls it.

Current vs. Expected behavior

router.push no longer called when using Link since 15.3

Provide environment information

Operating System:
  Platform: linux
  Arch: x64
  Version: #1 SMP PREEMPT_DYNAMIC Sat Feb  8 02:00:20 UTC 2025
  Available memory (MB): 32023
  Available CPU cores: 24
Binaries:
  Node: 23.11.0
  npm: 10.9.2
  Yarn: N/A
  pnpm: N/A
Relevant Packages:
  next: 15.3.0 // Latest available version is detected (15.3.0).
  eslint-config-next: 15.3.0
  react: 19.1.0
  react-dom: 19.1.0
  typescript: 5.8.3
Next.js Config:
  output: standalone

Which area(s) are affected? (Select all that apply)

Linking and Navigating

Which stage(s) are affected? (Select all that apply)

Other (Deployed)

Additional context

Many libraries are relying on monkey patching router.push due to the (very) limited router support Next.js provides. Since 15.3, Link stopped using router.push from context.

I understand monkey patching is an unsupported way of doing things, but there is simply no other way to handle specific cases, because Next doesn't provide any public APIs to give us control. I'd really like if it'd be considered

a. Using router.push again for navigation.
b. Giving us APIs and Events for granular control over routing.

This was the previous code:

const navigate = () => {
    // If the router is an NextRouter instance it will have `beforePopState`
    const routerScroll = scroll ?? true
    if ('beforePopState' in router) {
      router[replace ? 'replace' : 'push'](href, as, {
        shallow,
        scroll: routerScroll,
      })
    } else {
      router[replace ? 'replace' : 'push'](as || href, {
        scroll: routerScroll,
      })
    }
  }

This is currently with 15.3:

const navigate = () => {
    if (onNavigate) {
      let isDefaultPrevented = false

      onNavigate({
        preventDefault: () => {
          isDefaultPrevented = true
        },
      })

      if (isDefaultPrevented) {
        return
      }
    }

    dispatchNavigateAction(
      as || href,
      replace ? 'replace' : 'push',
      scroll ?? true,
      linkInstanceRef.current
    )
  }
@github-actions github-actions bot added the Linking and Navigating Related to Next.js linking (e.g., <Link>) and navigation. label Apr 12, 2025
@ryanelian
Copy link

ryanelian commented Apr 12, 2025

My top progress bar broke.

Can we useLinkStatus that works on server or client and be used outside Link component?

I just want to show a progress bar when a navigation / server-side await / page loading is currently ongoing.

This is my use case that got broken by the 15.3 update:

export function NextClientProgressBar() {
	const [loading, setLoading] = useOptimistic(false);
	const router = useRouter();
	const [, startTransition] = useTransition();

	useEffect(() => {
		if (router.push.name === "patched") {
			return;
		}

		const push = router.push;
		router.push = function patched(...args) {
			startTransition(() => {
				setLoading(true);
				push.apply(history, args);
			});
		};
	}, [router, setLoading]);

	return <AnimatePresence>{loading && <GlobalProgressBar />}</AnimatePresence>;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Linking and Navigating Related to Next.js linking (e.g., <Link>) and navigation.
Projects
None yet
Development

No branches or pull requests

2 participants