A VuePress plugin that automatically activates sidebar links when the page scrolls
npx @tessl/cli install tessl/npm-vuepress--plugin-active-header-links@1.9.0The VuePress Active Header Links Plugin automatically activates sidebar links when the page scrolls, providing visual feedback to users about their current position in the document. It monitors scroll events and determines which header anchor is currently visible, then updates the browser's hash and highlights the corresponding sidebar link.
npm install @vuepress/plugin-active-header-links// In VuePress config file
module.exports = {
plugins: ['@vuepress/active-header-links']
}Plugin Development Dependencies:
const { path } = require('@vuepress/shared-utils');
import debounce from 'lodash.debounce';// Basic plugin registration
module.exports = {
plugins: ['@vuepress/active-header-links']
}
// With custom configuration options
module.exports = {
plugins: ['@vuepress/active-header-links', {
sidebarLinkSelector: '.sidebar-link',
headerAnchorSelector: '.header-anchor'
}]
}Creates and configures the VuePress plugin with optional settings for CSS selectors.
/**
* Main plugin export - factory function that creates the active header links plugin
* @param {PluginOptions} options - Configuration options for the plugin (defaults to empty object)
* @returns {PluginObject} VuePress plugin object
*/
const { path } = require('@vuepress/shared-utils');
module.exports = (options = {}) => ({
clientRootMixin: path.resolve(__dirname, 'clientRootMixin.js'),
define: {
AHL_SIDEBAR_LINK_SELECTOR: options.sidebarLinkSelector || '.sidebar-link',
AHL_HEADER_ANCHOR_SELECTOR: options.headerAnchorSelector || '.header-anchor'
}
});
interface PluginOptions {
/** CSS selector for sidebar links (default: '.sidebar-link') */
sidebarLinkSelector?: string;
/** CSS selector for header anchors (default: '.header-anchor') */
headerAnchorSelector?: string;
}
interface PluginObject {
/** Path to client-side mixin file */
clientRootMixin: string;
/** Global constants for client-side usage */
define: {
AHL_SIDEBAR_LINK_SELECTOR: string;
AHL_HEADER_ANCHOR_SELECTOR: string;
};
}
// TypeScript type support from @vuepress/types
type Plugin<T extends PluginOptions = PluginOptions> =
(options: T) => PluginObject;Usage Examples:
// Default configuration
module.exports = {
plugins: ['@vuepress/active-header-links']
}
// Custom selectors for different theme structure
module.exports = {
plugins: ['@vuepress/active-header-links', {
sidebarLinkSelector: '.custom-sidebar-link',
headerAnchorSelector: '.custom-header-anchor'
}]
}
// Using full plugin name
module.exports = {
plugins: [
['@vuepress/plugin-active-header-links', {
sidebarLinkSelector: '.nav-link',
headerAnchorSelector: '.anchor-link'
}]
]
}The plugin automatically injects client-side functionality that provides smooth scrolling behavior and active link highlighting.
Client-Side Implementation:
The plugin injects a Vue.js mixin (clientRootMixin.js) that provides:
// Vue.js mixin pattern
import debounce from 'lodash.debounce';
export default {
mounted() {
window.addEventListener('scroll', this.onScroll);
},
methods: {
onScroll: debounce(function() {
this.setActiveHash();
}, 300),
setActiveHash() {
// Active header detection logic
}
},
beforeDestroy() {
window.removeEventListener('scroll', this.onScroll);
}
};Scroll Event Handling:
Active Link Detection Algorithm:
Hash Management:
$route.hash to maintain navigation statedecodeURIComponent for proper Unicode support in anchorsthis.$vuepress.$set('disableScrollBehavior', true) for scroll managementthis.$router.replace()CSS selector for sidebar navigation links.
sidebarLinkSelector?: string = '.sidebar-link'This selector is used to find sidebar links that should be activated based on the current scroll position. The plugin will match these links with corresponding header anchors on the page.
CSS selector for header anchor elements.
headerAnchorSelector?: string = '.header-anchor'This selector identifies the anchor elements within headers that are used for navigation. These anchors must have hash properties that correspond to sidebar link destinations.
Dependencies:
@vuepress/shared-utils: Used for path resolution utilitieslodash.debounce: Used for scroll event debouncing (300ms delay)VuePress Plugin System:
clientRootMixin mechanism for client-side functionalityDOM Structure Requirements:
hash properties matching header anchorsoffsetTop propertiesdocument.querySelectorAll()Browser Compatibility:
The plugin gracefully handles common scenarios: