Skip to content

Commit

Permalink
fix(21606): consider scroll option when using shallow routing (#24888)
Browse files Browse the repository at this point in the history
## Bug

- [x] Related issues linked using `fixes #number`
- [ ] Integration tests added

fixes [#21606](#21606)

### Description
When using shallow routing and wanting to scroll to top by setting the `scroll` option to `true` it didn't work. This PR fixes this issue.
  • Loading branch information
chrisneven committed Jun 8, 2021
1 parent 5072518 commit d820542
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 14 deletions.
4 changes: 2 additions & 2 deletions packages/next/client/link.tsx
Expand Up @@ -94,8 +94,8 @@ function linkClicked(
e.preventDefault()

// avoid scroll for urls with anchor refs
if (scroll == null) {
scroll = as.indexOf('#') < 0
if (scroll == null && as.indexOf('#') >= 0) {
scroll = false
}

// replace state instead of push if prop is present
Expand Down
16 changes: 6 additions & 10 deletions packages/next/next-server/lib/router/router.ts
Expand Up @@ -816,11 +816,6 @@ export default class Router implements BaseRouter {
this.isReady = true
}

// Default to scroll reset behavior unless explicitly specified to be
// `false`! This makes the behavior between using `Router#push` and a
// `<Link />` consistent.
options.scroll = !!(options.scroll ?? true)

let localeChange = options.locale !== this.locale

if (process.env.__NEXT_I18N_SUPPORT) {
Expand Down Expand Up @@ -1165,9 +1160,6 @@ export default class Router implements BaseRouter {
!(routeInfo.Component as any).getInitialProps
}

// shallow routing is only allowed for same page URL changes.
const isValidShallowRoute = options.shallow && this.route === route

if (
(options as any)._h &&
pathname === '/_error' &&
Expand All @@ -1179,14 +1171,18 @@ export default class Router implements BaseRouter {
props.pageProps.statusCode = 500
}

// shallow routing is only allowed for same page URL changes.
const isValidShallowRoute = options.shallow && this.route === route

const shouldScroll = options.scroll ?? !isValidShallowRoute
const resetScroll = shouldScroll ? { x: 0, y: 0 } : null
await this.set(
route,
pathname!,
query,
cleanedAs,
routeInfo,
forcedScroll ||
(isValidShallowRoute || !options.scroll ? null : { x: 0, y: 0 })
forcedScroll ?? resetScroll
).catch((e) => {
if (e.cancelled) error = error || e
else throw e
Expand Down
Expand Up @@ -22,10 +22,10 @@ export default withRouter(
return router.query.counter ? parseInt(router.query.counter) : 0
}

increase() {
increase(scroll) {
const counter = this.getCurrentCounter()
const href = `/nav/shallow-routing?counter=${counter + 1}`
Router.push(href, href, { shallow: true })
Router.push(href, href, { shallow: true, scroll })
}

increaseNonShallow() {
Expand Down Expand Up @@ -56,6 +56,9 @@ export default withRouter(
<button id="increase" onClick={() => this.increase()}>
Increase
</button>
<button id="increaseWithScroll" onClick={() => this.increase(true)}>
Increase with scroll
</button>
<button id="increase2" onClick={() => this.increaseNonShallow()}>
Increase Non-Shallow
</button>
Expand Down
16 changes: 16 additions & 0 deletions test/integration/client-navigation/test/index.test.js
Expand Up @@ -881,6 +881,22 @@ describe('Client Navigation', () => {
})
})

it('should scroll to top when the scroll option is set to true', async () => {
const browser = await webdriver(context.appPort, '/nav/shallow-routing')
await browser.eval(() =>
document.querySelector('#increaseWithScroll').scrollIntoView()
)
const scrollPosition = await browser.eval('window.pageYOffset')

expect(scrollPosition).toBeGreaterThan(3000)

await browser.elementByCss('#increaseWithScroll').click()
await check(async () => {
const newScrollPosition = await browser.eval('window.pageYOffset')
return newScrollPosition === 0 ? 'success' : 'fail'
}, 'success')
})

describe('with URL objects', () => {
it('should work with <Link/>', async () => {
const browser = await webdriver(context.appPort, '/nav')
Expand Down

0 comments on commit d820542

Please sign in to comment.