To allow for advanced usage of routing we currently have the capability to use Link and router.push/replace with unmatched/incompatible href and as values.
For example, we are able to do the following:
Router.push(`/user?photoId=${id}`, `/user/photo?id=${id}`)
This allows developers to implement advanced routing UX such as instagram style modals, where a modal can open on the same page but also have a dedicated page.
The current challenge is that when a dynamic element is added to the values an error is emitted noting incompatible href and as values - https://github.com/zeit/next.js/blob/master/errors/incompatible-href-as.md
For example:
Router.push(`/[user]?photoId=${id}`, `/user/photo?id=${id}`)
The reason this error is produced is due to the following section of code, which checks both values match:
https://github.com/zeit/next.js/blob/69b7538dce2fa8853bccfa2f65c8c305d76daae3/packages/next/next-server/lib/router/router.ts#L319
On removing this check all routing functions as expected (including the dynamic route) and all tests still pass.
For this reason I would like to request that this section of code is reviewed and potentially removed.
An alternative solution is to allow a flag that disables this route match check, potentially reducing features for this situation and/or allowing for an at risk implementation (if there is a risk introduced when removing this route match check)
I have forked an instagram clone, updating the next package to the latest version and introduced a dynamic route.
When disabling the section of code noted above all routing functionality works as expected:
https://github.com/tomevans18/nextagram
I have also forked next.js and commented out the section of code noted above.
When running the tests against this repo, all routing tests pass:
https://github.com/tomevans18/next.js
If there is any additional investigation work that needs to be done to help this feature happen please let me know and I will be happy to oblige.
I would also appreciate this pattern working or some idea on how to achieve it in light of the emitted error. I asked on Spectrum a few months ago but it didn't get far that way.
There used to be a Next.js example built by Guillermo Rauch floating around called nextgram that showcased the Instagram style modals and url pattern you described. It was one of the original key inspirations for us trying and then moving to Next.js. I don't think the example would work with the modern dynamic url syntax.
I would also appreciate having this feature. Currently, my URLs are like
/:category?searchQuery=search-item
which I would like to convert to
/:category/search/:search-item
Linking to #9081, as this will probably need fixed due to the addition of rewrites.
@tomevans18 Thanks for your work on this.
@Timer This is a crucial requirement for me. Instagram style modals are increasingly in demand and make for a much nicer user experience when viewing assets on a long list (like one with infinite scroll).
So anything I can do to help with this, please let me know.
@Timer @tomevans18
If nobody's working on this, I can take a crack at it. Let me know if I should hold back.
There's already an open PR as you can see on the issue timeline: #9837
@timneutkens haha, I know. It鈥檚 not a great solution to achieving Instagram style modals, though. I鈥檒l draft a separate PR with a different proposal.
Highly recommend writing up what you're planning to do first as it's unlikely we'll merge a PR changing routing behavior.
@Timer @timneutkens Sorry, I confused @tomevans18 solution (merely commenting out the routeMatch check) with @Timer 's PR. My bad.
PR #9837 is an elegant solution. Just tried it out, and it works perfectly for Instagram style modals.
May I ask what's holding this back from being merged? And what might be the expected merge ETA?
Supported in ^9.2.1-canary.6. Please give it a try!
@Timer Thank you so much!!!
Late to the party. I had me notifications disabled so missed it all!
Really awesome to see this implemented. Thanks @Timer and the rest of the team, I appreciate routing is a complicated area to change/improve.
I've updated to 9.2.1 for this but I still get the error:
Uncaught (in promise) Error: The provided `as` value (/slug/project/post/618746458) is incompatible with the `href` value (/project/post/[id]). Read more: https://err.sh/zeit/next.js/incompatible-href-as
<Link href="/project/post/[id]" as={PREFIX + '/project/post/' + id} passHref>
<Button>Example</Button>
</Link>
Fixed by changing the structure of the link to:
<Link href={`/project/post?id=${id}`} as={`${PREFIX}/project/post/${id}`} passHref>
<Button>Example</Button>
</Link>
Most helpful comment
Supported in
^9.2.1-canary.6. Please give it a try!