BScrollspy
Add automatic active-state tracking to navigation links with the v-b-scrollspy directive. It watches a content container and applies active classes to matching links as the user scrolls.
The
v-b-scrollspydirective is the declarative counterpart touseScrollspy. Apply it to a navigation container and point it at the scrollable content area to automatically keep matching links in sync with scroll position.
Introduction
The scrollspy directive watches a content container and automatically applies the active class to matching navigation links.
Scroll this panel to see the active link on the left update as different sections enter view.
Usage
Apply v-b-scrollspy to a navigation wrapper and point it at a scrollable content element that contains headings or sections with IDs.
Links inside the navigation must use matching fragment identifiers such as #scrollspy-usage.
Options
Use an object value when you need to customize the tracked selector, observer root, or mutation watching behavior.
For full programmatic control, use the useScrollspy composable instead of the directive.
<BContainer>
<BRow>
<BCol cols="4">
<BListGroup v-b-scrollspy:directive-overview-content>
<BListGroupItem href="#scrollspy-introduction">Introduction</BListGroupItem>
<BListGroupItem href="#scrollspy-usage">Usage</BListGroupItem>
<BListGroupItem href="#scrollspy-options">Options</BListGroupItem>
</BListGroup>
</BCol>
<BCol cols="8">
<div
id="directive-overview-content"
style="height: 260px; overflow-y: auto; border: 1px solid #dee2e6; padding: 1rem"
>
<h5 id="scrollspy-introduction">Introduction</h5>
<p>
The scrollspy directive watches a content container and automatically applies the
<code>active</code> class to matching navigation links.
</p>
<p>
Scroll this panel to see the active link on the left update as different sections enter
view.
</p>
<h5 id="scrollspy-usage">Usage</h5>
<p>
Apply <code>v-b-scrollspy</code> to a navigation wrapper and point it at a scrollable
content element that contains headings or sections with IDs.
</p>
<p>
Links inside the navigation must use matching fragment identifiers such as
<code>#scrollspy-usage</code>.
</p>
<h5 id="scrollspy-options">Options</h5>
<p>
Use an object value when you need to customize the tracked selector, observer root, or
mutation watching behavior.
</p>
<p>
For full programmatic control, use the <code>useScrollspy</code> composable instead of
the directive.
</p>
</div>
</BCol>
</BRow>
</BContainer>Overview
Things to know when using the scrollspy directive:
- Apply the directive to the navigation container (
BNav,BListGroup, or similar) - Point it at the content container that contains elements with
idattributes - Navigation links must use matching fragment
hrefvalues likehref="#section-id" - The directive adds and removes the
activeclass on matching links as the content scrolls v-b-scrollspyhandles active-state tracking only. If you also want click-to-scroll behavior, useuseScrollspy
Directive Syntax
As shown above, the BootstrapVueNext directive v-b-scrollspy can use either an argument or a value to identify the content container:
<BNav v-b-scrollspy:content-area />
<BNav v-b-scrollspy="'#content-area'" />
<BNav v-b-scrollspy="{content: '#content-area', contentQuery: '.section[id]'}" />The content target can be:
- A raw element ID such as
content-area - A selector string such as
#content-area - An object with
content(orelement) plus anyuseScrollspyoptions
Passing Options
When you use an object value, v-b-scrollspy forwards the remaining properties to useScrollspy. This lets you customize matching and observer behavior without writing setup code.
| Option | Type | Default | Description |
|---|---|---|---|
content | string | ComponentPublicInstance | HTMLElement | null | — | Content container to observe |
element | string | ComponentPublicInstance | HTMLElement | null | — | Alias for content |
contentQuery | string | ':scope > [id]' | CSS selector for tracked content elements |
targetQuery | string | '[href]' | CSS selector for links inside the directive host element |
manual | boolean | false | Disable automatic active class management |
root | string | ComponentPublicInstance | HTMLElement | null | null | Custom root for the intersection observer |
rootMargin | string | '0px 0px -25%' | Margin around the observer root |
threshold | number | number[] | [0.1, 0.5, 1] | Intersection observer thresholds |
watchChanges | boolean | true | Refresh tracked content automatically when DOM changes |
Dynamic Content
By default, the directive watches the content container for child-list changes, so newly added sections are tracked automatically. If your content is static and you want to avoid that observer, set watchChanges: false.
Accessibility and Structure
- Keep the directive on keyboard-focusable navigation links and containers
- Make sure each tracked section has a unique
id - Make sure each navigation item points to a tracked section with a matching fragment
href
See Also
- useScrollspy - The underlying composable for click-to-scroll helpers and manual control
- BNav - Common navigation target for scrollspy links
- BListGroup - Another good fit for scrollspy navigation