Edit

+keepScrollPosition

Environment: client
type Val = boolean | string | string[]
type KeepScrollPosition =
  | Val
  | ((pageContext: PageContextClient) => Val)

Default: false
Per-page
Config for vike

The keepScrollPosition setting enables you to control whether the page scrolls to the top upon navigation.

It's commonly used for nested layouts such as tabs, see API > +Layout > Nested.

For a control on a link-by-link basis, see <a href="/some-url" keep-scroll-position />.

Basics

By default, the page is scrolled to the top upon navigation. But if you set keepScrollPosition to true then the page's scroll position is preserved instead.

// pages/product/@id/+config.js
 
export default {
  // Don't scroll to top when navigating between the pages defined at pages/product/@id/**
  keepScrollPosition: true
}
// pages/product/@id/+config.ts
 
import type { Config } from 'vike/types'
 
export default {
  // Don't scroll to top when navigating between the pages defined at pages/product/@id/**
  keepScrollPosition: true
} satisfies Config
pages/product/@id/+config.js
pages/product/@id/pricing/+Page.js
pages/product/@id/reviews/+Page.js
pages/product/@id/+config.ts
pages/product/@id/pricing/+Page.ts
pages/product/@id/reviews/+Page.ts
# Scroll is preserved when navigating between:
/product/42
/product/42/pricing
/product/42/reviews
 
# Scroll is preserved when navigating between:
/product/1337
/product/1337/pricing
/product/1337/reviews

Note that the scroll isn't preserved (the page scrolls to the top) if the @id parameter differs.

# Scroll *isn't* preserved when navigating between:
/product/42/pricing
/product/1337/pricing

See Advanced if this behavior doesn't fit your use case.

Advanced

You can preserve the scroll position between any arbitrary group of pages (the "scroll group").

// /pages/product/@id/+config.js
 
export default {
  keepScrollPosition: 'name-of-the-scroll-group'
}
// /pages/product/@id/+config.ts
 
import type { Config } from 'vike/types'
 
export default {
  keepScrollPosition: 'name-of-the-scroll-group'
} satisfies Config
# Scroll is preserved when navigating between:
/product/42/pricing
/product/1337/pricing
// /pages/reviews/@id/+config.js
 
export default {
  keepScrollPosition: 'name-of-the-scroll-group'
}
// /pages/reviews/@id/+config.ts
 
import type { Config } from 'vike/types'
 
export default {
  keepScrollPosition: 'name-of-the-scroll-group'
} satisfies Config
# Scroll is preserved when navigating between:
/product/42
/reviews/1337

If two URLs belong to the same scroll group, then the scroll position is preserved.

You can also programmatically set the scroll group:

// /pages/product/@id/+keepScrollPosition.js
// Environment: client
 
export function keepScrollPosition(pageContext, { configDefinedAt }) {
  console.log(configDefinedAt) // /pages/product/@id/+keepScrollPosition.js
  // This is the value Vike sets by default:
  return [configDefinedAt, pageContext.routeParams['id']]
}
// /pages/product/@id/+keepScrollPosition.ts
// Environment: client
 
import type { PageContextClient } from 'vike/types'
 
export function keepScrollPosition(
  pageContext: PageContextClient,
  { configDefinedAt }: { configDefinedAt: string }
) {
  console.log(configDefinedAt) // /pages/product/@id/+keepScrollPosition.ts
  // This is the value Vike sets by default:
  return [configDefinedAt, pageContext.routeParams['id']]
}

See also