From 2616aadda6477743da7e185d45eeae022bd0f1b1 Mon Sep 17 00:00:00 2001 From: Prashant Palikhe Date: Sun, 30 Jul 2023 12:07:01 +0200 Subject: [PATCH] feat(nuxt): allow dynamic `scrollToTop` page meta (#21741) --- docs/3.api/3.utils/define-page-meta.md | 7 +++++++ packages/nuxt/src/pages/runtime/composables.ts | 2 +- packages/nuxt/src/pages/runtime/router.options.ts | 4 +++- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/docs/3.api/3.utils/define-page-meta.md b/docs/3.api/3.utils/define-page-meta.md index 3380d66479..5372e0bbb8 100644 --- a/docs/3.api/3.utils/define-page-meta.md +++ b/docs/3.api/3.utils/define-page-meta.md @@ -32,6 +32,7 @@ interface PageMeta { keepalive?: boolean | KeepAliveProps layout?: false | LayoutKey | Ref | ComputedRef middleware?: MiddlewareKey | NavigationGuard | Array + scrollToTop?: boolean | ((to: RouteLocationNormalizedLoaded, from: RouteLocationNormalizedLoaded) => boolean) [key: string]: unknown } ``` @@ -98,6 +99,12 @@ interface PageMeta { Validate whether a given route can validly be rendered with this page. Return true if it is valid, or false if not. If another match can't be found, this will mean a 404. You can also directly return an object with `statusCode`/`statusMessage` to respond immediately with an error (other matches will not be checked). + **`scrollTopTop`** + + - **Type**: `boolean | (to: RouteLocationNormalized, from: RouteLocationNormalized) => boolean` + + Tell Nuxt to scroll to the top before rendering the page or not. If you want to overwrite the default scroll behavior of Nuxt, you can do so in `~/app/router.options.ts` (see [docs](/docs/guide/directory-structure/pages/#router-options)) for more info. + **`[key: string]`** - **Type**: `any` diff --git a/packages/nuxt/src/pages/runtime/composables.ts b/packages/nuxt/src/pages/runtime/composables.ts index 3fde4c6ccb..a57d83371d 100644 --- a/packages/nuxt/src/pages/runtime/composables.ts +++ b/packages/nuxt/src/pages/runtime/composables.ts @@ -36,7 +36,7 @@ export interface PageMeta { /** You may define a path matcher, if you have a more complex pattern than can be expressed with the file name. */ path?: string /** Set to `false` to avoid scrolling to top on page navigations */ - scrollToTop?: boolean + scrollToTop?: boolean | ((to: RouteLocationNormalizedLoaded, from: RouteLocationNormalizedLoaded) => boolean) } declare module 'vue-router' { diff --git a/packages/nuxt/src/pages/runtime/router.options.ts b/packages/nuxt/src/pages/runtime/router.options.ts index d5c8bdbb59..42de00df3d 100644 --- a/packages/nuxt/src/pages/runtime/router.options.ts +++ b/packages/nuxt/src/pages/runtime/router.options.ts @@ -20,8 +20,10 @@ export default { // savedPosition is only available for popstate navigations (back button) let position: ScrollPosition = savedPosition || undefined + const routeAllowsScrollToTop = typeof to.meta.scrollToTop === 'function' ? to.meta.scrollToTop(to, from) : to.meta.scrollToTop + // Scroll to top if route is changed by default - if (!position && from && to && to.meta.scrollToTop !== false && _isDifferentRoute(from, to)) { + if (!position && from && to && routeAllowsScrollToTop !== false && _isDifferentRoute(from, to)) { position = { left: 0, top: 0 } }