Scroll & focus management
What should happen to the viewport - and to keyboard/screen-reader focus - after each
navigation. All configured once, on BrouterOptions.
The four knobs
These DOM effects run once the matched route is committed, so fragment and focus selectors resolve against the new page. During static prerender they are skipped - there is no DOM to act on.
| Option | Behavior |
|---|---|
| ScrollBehavior | ToTop scrolls the window to the top on navigation (default None - SPAs otherwise keep the old scroll position on the new page). |
| ScrollToFragment | Navigating to /docs#install scrolls #install into view and focuses it. Default on; a found fragment target wins over everything else that navigation. |
| RestoreScrollPosition | Remembers each page's scroll position and restores it on Back/Forward, like native browsers. New navigations still use ScrollBehavior. Default off; enabling takes over history.scrollRestoration. |
| FocusOnNavigateSelector | Moves focus to a selector (e.g. "h1") after navigation so assistive technologies announce the new page - the SPA-router counterpart of Blazor's <FocusOnNavigate>, and a WCAG-relevant concern. Non-focusable targets get tabindex="-1". |
builder.Services.AddBitBrouterServices(o =>
{
o.ScrollBehavior = BrouterScrollMode.ToTop;
o.ScrollToFragment = true;
o.RestoreScrollPosition = true;
o.ScrollPositionStorage = BrouterScrollPositionStorage.SessionStorage;
o.FocusOnNavigateSelector = "h1";
});Where restored positions live
ScrollPositionStorage picks the store for remembered positions:
Memory (default - lost on a full reload), SessionStorage
(recommended: per-tab, auto-cleared on tab close, survives reloads), or
LocalStorage (survives restarts, shared across tabs). If the chosen store is
unavailable (private mode, quota), it falls back to memory.
Precedence when several apply
If a fragment target resolves, it scrolls into view and takes focus - nothing else runs
that navigation. Otherwise, a Back/Forward with a remembered position restores it, else
ScrollBehavior applies; and only in these non-fragment cases does
FocusOnNavigateSelector then receive focus.
Navigation type awareness
Scroll restoration is driven by BrouterNavigationContext.NavigationType
(Push / Replace / Pop) - the same signal your own
guards, loaders and hooks can branch on for "treat Back differently" logic like reusing
cached data on a Pop. See
navigation & history.