Skip to content
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

fix(nuxt): scroll to top by default on dynamic routes #22403

Merged
merged 18 commits into from Sep 6, 2023
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 3 additions & 3 deletions packages/nuxt/src/pages/runtime/router.options.ts
Expand Up @@ -63,12 +63,12 @@ function _getHashElementScrollMarginTop (selector: string): number {
}

function _isDifferentRoute (from: RouteLocationNormalized, to: RouteLocationNormalized): boolean {
const samePageComponent = to.matched.every((comp, index) => comp.components?.default === from.matched[index]?.components?.default)
const isSamePath = to.path === from.path

if (!samePageComponent) {
if (!isSamePath) {
return true
}
if (samePageComponent && JSON.stringify(from.params) !== JSON.stringify(to.params)) {
if (isSamePath && JSON.stringify(from.params) !== JSON.stringify(to.params)) {
huang-julien marked this conversation as resolved.
Show resolved Hide resolved
return true
}
return false
Expand Down
50 changes: 50 additions & 0 deletions test/basic.test.ts
Expand Up @@ -533,6 +533,56 @@ describe('nuxt links', () => {

await page.close()
})

it('expect scroll to top on routes with same component', async () => {
// #22402
const page = await createPage('/big-page-1')
await page.setViewportSize({
width: 1000,
height: 1000
})
await page.waitForLoadState('networkidle')

await page.locator('#big-page-2').scrollIntoViewIfNeeded()
expect(await page.evaluate(() => window.scrollY)).toBeGreaterThan(0)
await page.locator('#big-page-2').click()
await page.waitForURL(url => url.href.includes('/big-page-2'))
await page.waitForTimeout(25)
expect(await page.evaluate(() => window.scrollY)).toBe(0)

await page.locator('#big-page-1').scrollIntoViewIfNeeded()
expect(await page.evaluate(() => window.scrollY)).toBeGreaterThan(0)
await page.locator('#big-page-1').click()
await page.waitForURL(url => url.href.includes('/big-page-1'))
await page.waitForTimeout(25)
expect(await page.evaluate(() => window.scrollY)).toBe(0)
await page.close()
})

it('expect scroll to top on nested pages', async () => {
// #20523
const page = await createPage('/nested/foo/test')
await page.setViewportSize({
width: 1000,
height: 1000
})
await page.waitForLoadState('networkidle')

await page.locator('#user-test').scrollIntoViewIfNeeded()
expect(await page.evaluate(() => window.scrollY)).toBeGreaterThan(0)
await page.locator('#user-test').click()
await page.waitForURL(url => url.href.includes('/nested/foo/user-test'))
await page.waitForTimeout(25)
expect(await page.evaluate(() => window.scrollY)).toBe(0)

await page.locator('#test').scrollIntoViewIfNeeded()
expect(await page.evaluate(() => window.scrollY)).toBeGreaterThan(0)
await page.locator('#test').click()
await page.waitForURL(url => url.href.includes('/nested/foo/test'))
await page.waitForTimeout(25)
expect(await page.evaluate(() => window.scrollY)).toBe(0)
await page.close()
})
})

describe('head tags', () => {
Expand Down
Expand Up @@ -12,7 +12,13 @@ export default defineNuxtModule({
pages.push({
name: 'page-extend',
path: '/page-extend',
file: resolver.resolve('./runtime/page.vue')
file: resolver.resolve('../runtime/page.vue')
}, {
path: '/big-page-1',
file: '@/modules/page-extend/pages/big-page.vue'
}, {
path: '/big-page-2',
file: '@/modules/page-extend/pages/big-page.vue'
})
})
}
Expand Down
36 changes: 36 additions & 0 deletions test/fixtures/basic/modules/page-extend/pages/big-page.vue
@@ -0,0 +1,36 @@
<template>
<div>
<div class="big-block">
big
</div>
<div class="big-block">
page
</div>
<NuxtLink id="big-page-1" to="/big-page-1">
to big page 1
</NuxtLink>
<NuxtLink id="big-page-2" to="/big-page-2">
to big page 2
</NuxtLink>
<NuxtLink id="big-page-2-test-test" to="/big-page-2?test=test">
to big page 2 with ?test=test
</NuxtLink>
<NuxtLink id="big-page-2-test-super-test" to="/big-page-2?test=super-test">
to big page 2 with ?test=super-test
</NuxtLink>
</div>
</template>

<script setup>
definePageMeta({
layout: false
})
</script>

<style scoped>
.big-block {
height: 90vh;
width: 100vw;
background-color: brown;
}
</style>
3 changes: 3 additions & 0 deletions test/fixtures/basic/pages/index.vue
Expand Up @@ -53,6 +53,9 @@
<component :is="`with${'-'.toString()}suffix`" />
<ClientWrapped ref="clientRef" style="color: red;" class="client-only" />
<ServerOnlyComponent class="server-only" style="background-color: gray;" />
<NuxtLink to="/big-page-1">
to big 1
</NuxtLink>
</div>
</template>

Expand Down
Expand Up @@ -6,5 +6,16 @@ const route = useRoute('nested-foo')
<div>
<div>nested/[foo]/index.vue</div>
<div>foo: {{ route.params.foo }}</div>

<div class="big-block" />
<div class="big-block" />
<NuxtPage />
</div>
</template>

<style scoped>
.big-block {
height: 90vh;
width: 100vw;
}
</style>
6 changes: 6 additions & 0 deletions test/fixtures/basic/pages/nested/[foo]/[bar].vue
Expand Up @@ -7,5 +7,11 @@ const route = useRoute('nested-foo-bar')
<div>nested/[foo]/[bar].vue</div>
<div>foo: {{ route.params.foo }}</div>
<div>bar: {{ route.params.bar }}</div>
<NuxtLink id="user-test" to="/nested/foo/user-test">
to /nested/foo/user-test
</NuxtLink>
<NuxtLink id="test" to="/nested/foo/test">
to /nested/foo/test
</NuxtLink>
</div>
</template>
7 changes: 7 additions & 0 deletions test/fixtures/basic/pages/nested/[foo]/user-[group].vue
Expand Up @@ -7,5 +7,12 @@ const route = useRoute('nested-foo-user-group')
<div>nested/[foo]/user-[group].vue</div>
<div>foo: {{ route.params.foo }}</div>
<div>group: {{ route.params.group }}</div>

<NuxtLink id="user-test" to="/nested/foo/user-test">
to /nested/foo/user-test
</NuxtLink>
<NuxtLink id="test" to="/nested/foo/test">
to /nested/foo/test
</NuxtLink>
</div>
</template>