You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Docs: How to migrate from async router.push to new next/navigation push method #61737
What is the improvement or update you wish to see?
The new router in next/navigation no longer returns a promise from the push method. From what I've been able to understand, this is so that it can work with the startTransition feature of React, but the Next docs don't contain any information about this or how to successfully replace any functionality that was relying on "awaiting" a router.push call
Is there any context that might help us understand?
This is the one place I've been able to find mention of how it can be used with useTransition, although it also doesn't seem to trigger the pending state in many cases (maybe it just doesn't work in page router?) #49810
Does the docs page already exist? Please link to it.
'use client'import{useRouter}from'next/navigation'import{useEffect,useTransition}from'react'// Define the type for the observer callback functiontypeObserverCallback=()=>voidconstcreateRouteObserver=()=>{letobserver: ObserverCallback|null=nullconstsetObserver=(callback: ObserverCallback)=>{observer=callback}constnotify=()=>{if(observer){observer()}}return{ setObserver, notify }}constrouteObserver=createRouteObserver()exportconstuseAsyncRoutePush=()=>{const[isPending,startTransition]=useTransition()constrouter=useRouter()constasynPush=async(path: string)=>{returnnewPromise<void>((resolve)=>{startTransition(()=>{router.push(path)})routeObserver.setObserver(()=>{resolve()})})}useEffect(()=>{if(!isPending){routeObserver.notify()}},[isPending])returnasynPush}
Usage:
exportdefaultfunctionMyComponent(){constasyncPush=useAsyncRoutePush()return<ButtononClick={async()=>{awaitasyncPush('/')console.log("Route changed")}}>
Go / route
</Button>}
Reacted by Kovács Gergő, sjriccrv, Salman Mehmood, Kirill Groshkov, Ondřej Misák, Anatolii Pyroh, PO, Lucas Duarte, Kirill Markelov and Carlos León
This feature is really needed because I have an MUI grid which I added custom url tracking of the page in the url via push and when user clicks so fast since it's async all of it that means the router.push is not being awaited and clicking too fast is causing a crash look below
+1 This feature is really needed. It's been a year with no response? I don't know why the Next.js team prioritizes RSCs and server stuff while neglecting important features like these.
Activity
Guo-dalu commentedon Feb 7, 2024
Here here, also need it badly.
arcticfly commentedon May 22, 2024
Agreed. We built our own hacky solution to await router pushes, but would really like built-in support for this!
ArianHamdi commentedon May 22, 2024
Can you please share your workaround
arcticfly commentedon May 22, 2024
Cauen commentedon Jul 24, 2024
Here are an alternative implementation of https://stackoverflow.com/a/77931487/6638583 workaround code
Usage:
allicanseenow commentedon Sep 12, 2024
This should be mentioned in the documentation as a breaking change as there's no built-in support for this feature now.
TradeeHubDev commentedon Nov 12, 2024
This feature is really needed because I have an MUI grid which I added custom url tracking of the page in the url via push and when user clicks so fast since it's async all of it that means the router.push is not being awaited and clicking too fast is causing a crash look below
HasanMothaffar commentedon Feb 19, 2025
+1 This feature is really needed. It's been a year with no response? I don't know why the Next.js team prioritizes RSCs and server stuff while neglecting important features like these.
mhanzelka commentedon Sep 17, 2025
Still nothing? Is something what is keeping it back from implementing this in app router?
lucastnr commentedon Oct 2, 2025
I would love it implemented too, it's a bummer that we have to do it manually
daveidivide commentedon Oct 9, 2025
Same here, not enjoying writing hacks to get around the fact that router.push isn't async