BETA We're building something new — all help is welcome! Contribute →

v-scroll

Preserve scroll position of elements during SPA navigation.

Basic Usage

Mark elements that should have their scroll position saved and restored when navigating back/forward.

<!-- Auto-generated scroll key -->
<aside v-scroll class="overflow-y-auto h-screen">
    <!-- Sidebar content -->
</aside>

<!-- Named scroll key -->
<div v-scroll="'main-content'" class="overflow-y-auto">
    <!-- Scrollable content -->
</div>

How It Works

The directive sets a data-livue-scroll attribute on the element. When navigating with v-navigate or LiVue.navigate(), LiVue automatically:

  1. Saves the current scroll position of all marked elements before navigation
  2. Stores positions in sessionStorage for browser back/forward navigation
  3. Restores scroll positions when navigating to a cached page

This is useful for sidebars, navigation menus, and any scrollable containers that should maintain their position during SPA navigation.

Named Keys

Use named keys when you have multiple scrollable elements or want explicit control.

<div class="flex">
    <!-- Left sidebar -->
    <aside v-scroll="'left-sidebar'" class="w-64 overflow-y-auto">
        <!-- Navigation -->
    </aside>

    <!-- Main content -->
    <main v-scroll="'content'" class="flex-1 overflow-y-auto">
        <!-- Page content -->
    </main>

    <!-- Right sidebar -->
    <aside v-scroll="'right-sidebar'" class="w-64 overflow-y-auto">
        <!-- Table of contents -->
    </aside>
</div>

Auto-generated Keys

When no value is provided, the directive auto-generates a unique key. This is convenient for single scrollable elements.

<!-- These get unique keys: scroll-1, scroll-2, etc. -->
<aside v-scroll>...</aside>
<div v-scroll>...</div>

With SPA Navigation

Combine with v-navigate for a complete SPA experience with preserved scroll state.

<aside v-scroll="'sidebar'" class="overflow-y-auto">
    <a v-navigate href="/docs">Introduction</a>
    <a v-navigate href="/docs/installation">Installation</a>
    <a v-navigate href="/docs/components">Components</a>
    <!-- More links... -->
</aside>

When the user clicks a link and later navigates back, the sidebar scroll position is automatically restored.

Real example: The sidebar on this documentation site uses v-scroll="'docs-sidebar'" combined with v-navigate on all links. Try scrolling down in the sidebar, navigating to another page, then pressing back - the scroll position is preserved!

With @persist

For LiVue components that should preserve both their Vue state and scroll position, combine v-scroll with @persist.

Layout file
@persist('docs-sidebar')
    @livue('docs-sidebar')
@endpersist
Sidebar component template
<aside v-scroll="'sidebar'" class="overflow-y-auto h-screen">
    <a v-navigate href="/docs">...</a>
</aside>

The @persist preserves the Vue component's state and DOM, while v-scroll ensures the scroll position is also maintained during navigation.

Alternative: Data Attribute

You can also use the data attribute directly for elements outside of LiVue components.

<!-- Plain HTML without Vue component -->
<aside data-livue-scroll="sidebar">
    ...
</aside>

The navigation system reads data-livue-scroll from all elements in the DOM, regardless of whether they're inside a LiVue component.