Vue Router: Controlling Scroll Behavior
In a SPA, the browser doesn't manage scroll position; `scrollBehavior` is your manual override. Use it to scroll to top on new pages or restore position on back/forward. The footgun is forgetting `savedPosition`, breaking native back-button behavior.
WHY IT EXISTS In a Single Page Application, route changes happen on the client-side without a full page reload. This means the browser's default mechanism for handling scroll position—like remembering where you were when you hit the back button—is lost. scrollBehavior was created to give developers explicit control over this, re-enabling natural-feeling scroll management.
THE MENTAL MODEL Think of scrollBehavior as a bouncer for your page's viewport. Every time a user navigates, this function intercepts the event and asks, "Where should the user be looking now?". You provide the rules: "Always send them to the top," "If they're coming back, put them where they were," or "Send them to that specific section over there." Without these rules, users are left stranded wherever they were on the previous page.
HOW IT WORKS When you create your Vue Router instance, you provide a scrollBehavior function. This function receives three arguments: to (the route being navigated to), from (the route being left), and savedPosition. The savedPosition object, containing top and left coordinates, is only provided by the browser for history navigations (back/forward button clicks). Your function should return an object describing the desired position. You can return { top: 0 } to scroll to the top, return the savedPosition to restore a previous state, or return { el: '#my-id' } to scroll to a specific element. You can even return a Promise to delay the scroll, which is useful for coordinating with page transitions.
WHEN TO USE IT Use scrollBehavior to implement standard, expected web behaviors in your SPA. Three key use cases: first, scrolling to the top of the page on every new route navigation; second, restoring the user's scroll position when they use the browser's back and forward buttons; third, automatically scrolling to an element matching a URL hash, like page.com/profile#settings.
WHEN NOT TO USE IT Avoid implementing complex scroll logic if a simpler CSS-based solution like scroll-padding-top can reliably handle offsets for fixed headers. Over-engineering scrollBehavior with complex, asynchronous logic for simple cases can add unnecessary fragility. If you don't need to manage scroll position at all (e.g., in a full-screen, non-scrolling app), you don't need to define it.
ONE CANONICAL EXAMPLE A canonical implementation first checks if savedPosition exists. If it does, it returns savedPosition to restore the scroll state for back/forward navigation. If not, it checks if the to route has a hash. If it does, it returns an object like { el: to.hash, behavior: 'smooth' } to scroll smoothly to the anchor. As a final fallback for all other new navigations, it returns { top: 0, left: 0 } to scroll to the top of the page.
Read the original → router.vuejs.org
Get five bites like this every day.
Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.