1
0
Fork 0
mirror of https://github.com/terribleplan/next.js.git synced 2024-01-19 02:48:18 +00:00

Use as instead of url to determine URL newness (#4153)

Currently, using `as` will cause the router to think the URL is not changing in the case where you're re-rendering the same page with a different route. This would most likely be an issue for custom servers
which are using shallow routing.

This should be an invisible change for non-custom-server users, since `as` is defaulted to `url` if not set.

This should resolve #3065.
This commit is contained in:
George Pantazis 2018-09-03 06:26:34 -07:00 committed by Tim Neutkens
parent 400a04f487
commit 56ad5121a1
3 changed files with 41 additions and 1 deletions

View file

@ -171,13 +171,14 @@ export default class Router {
return true return true
} }
const { pathname: asPathname, query: asQuery } = parse(as, true)
const { pathname, query } = parse(url, true) const { pathname, query } = parse(url, true)
// If asked to change the current URL we should reload the current page // If asked to change the current URL we should reload the current page
// (not location.reload() but reload getInitialProps and other Next.js stuffs) // (not location.reload() but reload getInitialProps and other Next.js stuffs)
// We also need to set the method = replaceState always // We also need to set the method = replaceState always
// as this should not go into the history (That's how browsers work) // as this should not go into the history (That's how browsers work)
if (!this.urlIsNew(pathname, query)) { if (!this.urlIsNew(asPathname, asQuery)) {
method = 'replaceState' method = 'replaceState'
} }

View file

@ -0,0 +1,17 @@
import Link from 'next/link'
import {withRouter} from 'next/router'
export default withRouter(({router: {asPath, query}}) => {
return <div id={asPath.replace('/', '').replace('/', '-')}>
<div id='router-query'>{JSON.stringify(query)}</div>
<div>
<Link href='/nav/as-path-pushstate?something=hello' as='/something/hello'>
<a id='hello'>hello</a>
</Link>
</div>
{query.something === 'hello' && <Link href='/nav/as-path-pushstate?something=hello' as='/something/same-query'>
<a id='same-query'>same query</a>
</Link>}
</div>
})

View file

@ -633,6 +633,28 @@ export default (context, render) => {
browser.close() browser.close()
}) })
}) })
describe('with next/link', () => {
it('should use pushState with same href and different asPath', async () => {
let browser
try {
browser = await webdriver(context.appPort, '/nav/as-path-pushstate')
await browser.elementByCss('#hello').click().waitForElementByCss('#something-hello')
const queryOne = JSON.parse(await browser.elementByCss('#router-query').text())
expect(queryOne.something).toBe('hello')
await browser.elementByCss('#same-query').click().waitForElementByCss('#something-same-query')
const queryTwo = JSON.parse(await browser.elementByCss('#router-query').text())
expect(queryTwo.something).toBe('hello')
await browser.back().waitForElementByCss('#something-hello')
const queryThree = JSON.parse(await browser.elementByCss('#router-query').text())
expect(queryThree.something).toBe('hello')
} finally {
if (browser) {
browser.close()
}
}
})
})
}) })
describe('runtime errors', () => { describe('runtime errors', () => {