Description
UDashboardGroup is fixed inset-0 flex overflow-hidden and UDashboardPanel's body is flex-1 overflow-y-auto, so the document never scrolls — a panel inside it does. That's a deliberate app-shell design, but it means Nuxt's native scroll restoration cannot work, because both the browser and Vue Router operate on window:
vue-router records positions with const computeScrollPosition = () => ({ left: window.scrollX, top: window.scrollY }), which is permanently 0 inside a dashboard layout, so savedPosition is always { left: 0, top: 0 }.
- Nuxt's default
scrollBehavior (nuxt/dist/pages/runtime/router.options.js) ends in window.scrollTo(...) on every branch, including the { el } form, which resolves the element and then still scrolls the window.
The visible result is that scroll-to-top on navigation and back/forward restoration both do nothing. Clicking a row near the bottom of a long table opens the next route still scrolled to the same offset, and going back doesn't return you to your place in the list. Nothing errors, and nothing in the docs mentions it, so it reads as a Nuxt bug until you find the scroll container.
Request
Let the dashboard scroll the document instead of an inner panel — either as the default, or opt-in via a prop, e.g.:
<UDashboardGroup page-scroll>
The goal is specifically that Nuxt's own scroll restoration works with no custom code. Anything that keeps scrolling inside a nested container can't achieve that, since the framework only ever measures and sets window.
This is achievable today, but only by fighting the theme
It can be done in userland by overriding the theme, which is what we ended up doing:
- unpin the shell —
relative inset-auto min-h-svh overflow-visible on UDashboardGroup
fixed the sidebar and navbar so they hold the viewport edges
- offset the panel by the sidebar width to replace the flow width the fixed sidebar no longer occupies
It works, and Nuxt's scroll handling then behaves normally with zero custom scroll code. But it means re-implementing things the fixed shell provided implicitly, each of which only surfaces as a visual bug once the document scrolls:
- the sidebar has no background, so content scrolls visibly underneath it
- the sidebar and navbar have no
z-index, so ordinary page content using relative z-10 paints over them
Those are correct omissions under the current design and unavoidable breakage outside it, which is why this feels like it belongs in the library rather than in every app that wants it.
Additional context
Related to #5676, which asks for a scroll-region attribute so Inertia's scroll management can find the container — same root cause, different framework.
@nuxt/ui 4.10.0
nuxt 4.5.1
vue 3.5.39
Description
UDashboardGroupisfixed inset-0 flex overflow-hiddenandUDashboardPanel's body isflex-1 overflow-y-auto, so the document never scrolls — a panel inside it does. That's a deliberate app-shell design, but it means Nuxt's native scroll restoration cannot work, because both the browser and Vue Router operate onwindow:vue-routerrecords positions withconst computeScrollPosition = () => ({ left: window.scrollX, top: window.scrollY }), which is permanently0inside a dashboard layout, sosavedPositionis always{ left: 0, top: 0 }.scrollBehavior(nuxt/dist/pages/runtime/router.options.js) ends inwindow.scrollTo(...)on every branch, including the{ el }form, which resolves the element and then still scrolls the window.The visible result is that scroll-to-top on navigation and back/forward restoration both do nothing. Clicking a row near the bottom of a long table opens the next route still scrolled to the same offset, and going back doesn't return you to your place in the list. Nothing errors, and nothing in the docs mentions it, so it reads as a Nuxt bug until you find the scroll container.
Request
Let the dashboard scroll the document instead of an inner panel — either as the default, or opt-in via a prop, e.g.:
<UDashboardGroup page-scroll>The goal is specifically that Nuxt's own scroll restoration works with no custom code. Anything that keeps scrolling inside a nested container can't achieve that, since the framework only ever measures and sets
window.This is achievable today, but only by fighting the theme
It can be done in userland by overriding the theme, which is what we ended up doing:
relative inset-auto min-h-svh overflow-visibleonUDashboardGroupfixedthe sidebar and navbar so they hold the viewport edgesIt works, and Nuxt's scroll handling then behaves normally with zero custom scroll code. But it means re-implementing things the fixed shell provided implicitly, each of which only surfaces as a visual bug once the document scrolls:
z-index, so ordinary page content usingrelative z-10paints over themThose are correct omissions under the current design and unavoidable breakage outside it, which is why this feels like it belongs in the library rather than in every app that wants it.
Additional context
Related to #5676, which asks for a
scroll-regionattribute so Inertia's scroll management can find the container — same root cause, different framework.@nuxt/ui4.10.0nuxt4.5.1vue3.5.39