Takazudo

dev-docusaurus-sidebar-filter

Add a real-time filter/search input to a Docusaurus documentation site's sidebar. Swizzles the DocSidebar component to add a sticky text input that filters sidebar items (categories and docs) as the user types. Use when: (1) User wants to add sidebar filtering to a Docusaurus site, (2) User says 'sidebar filter', 'sidebar search', 'filter sidebar', 'docusaurus sidebar filter', (3) User wants to filter/search documentation navigation items in a Docusaurus sidebar.

Takazudo 10 1 Updated 3mo ago

Resources

1
GitHub

Install

npx skillscat add takazudo/claude-resources/dev-docusaurus-sidebar-filter

Install via the SkillsCat registry.

SKILL.md

Docusaurus Sidebar Filter

Add a real-time client-side filter input to a Docusaurus site's sidebar navigation. The filter searches both document labels and category names, with recursive child matching.

Prerequisites

  • Docusaurus v3.x project
  • TypeScript support (.tsx files)

Implementation Steps

Step 1: Detect Docusaurus Root

Find the Docusaurus project root by locating docusaurus.config.ts (or .js). All paths below are relative to this root.

Step 2: Swizzle DocSidebar (Wrap Mode)

Create the swizzled DocSidebar component. Use the asset file as the template:

Source: Read assets/DocSidebar-index.tsx from this skill directory.
Target: src/theme/DocSidebar/index.tsx

Copy the asset file content to the target path. Then customize:

  1. Placeholder text - Change "Filter docs..." to match the project's language:
  • Japanese: "ドキュメントを検索..."
  • English: "Filter docs..." (default)
  • Or whatever the user prefers
  1. Search input height - SEARCH_INPUT_HEIGHT is '57px' (padding 12px2 + input padding 8px2 + font ~14px + border 1px). Adjust only if changing padding/font values.

Step 3: Add Sidebar CSS to custom.css

Append these styles to the project's src/css/custom.css. These improve sidebar readability, especially for Japanese text, and add border separators between items:

/* === Sidebar filter enhancement styles === */

/* Improve line-height for sidebar items (especially useful for CJK text) */
.menu__list * {
  line-height: 1.8;
}

/* Border-separated menu items for visual clarity */
ul.menu__list > li {
  padding: 0.2em 0 0;
  border-top: 1px solid var(--ifm-color-emphasis-200);
}

ul.menu__list > li:first-child {
  border-top: none;
}

/* Restore border for nested first children */
ul.menu__list ul.menu__list > li:first-child {
  border-top: 1px solid var(--ifm-color-emphasis-200);
}

.menu__list-item {
  margin: 0;
}

.menu__link {
  padding: 0.55rem 0.4rem 0.35rem;
  border-radius: 0.25rem;
  line-height: 1.6;
  font-size: 0.95rem;
}

/* Caret arrow adjustments */
.menu__link--sublist-caret {
  padding-right: 1.5rem;
  position: relative;
}

.menu__link--sublist-caret::after {
  position: absolute !important;
  right: 0.7rem !important;
  top: 50% !important;
  transform: translateY(-50%) rotate(90deg) !important;
  margin: 0 !important;
}

.menu__list-item--collapsed .menu__link--sublist-caret::after {
  transform: translateY(-50%) rotate(90deg) !important;
}

li:not(.menu__list-item--collapsed) .menu__link--sublist-caret::after {
  transform: translateY(-50%) rotate(180deg) !important;
}

/* Spacing between main category items */
.theme-doc-sidebar-item-category {
  margin-top: 1rem;
}

.theme-doc-sidebar-item-category:first-child {
  margin-top: 0;
}

Important: Check if any of these selectors already exist in custom.css before appending. Merge with existing rules if needed.

Step 4: Verify

After implementing, verify:

  1. src/theme/DocSidebar/index.tsx exists with the filter component
  2. src/css/custom.css has the sidebar styles
  3. Run the dev server to confirm:
  • Filter input appears at the top of the sidebar
  • Typing filters both doc labels and category names
  • Clearing the input restores the full sidebar
  • Filter input stays sticky while scrolling the sidebar

How the Filter Works

  • Sticky input: Fixed at top of sidebar, below navbar, using position: sticky and top: var(--ifm-navbar-height)
  • Recursive filtering: Searches all levels of the sidebar tree
  • Category matching: A category is shown if its name matches OR any child matches
  • Performance: Uses useMemo to avoid re-filtering on every render
  • CSS scroll fix: Injects a <style> tag to adjust sidebar scroll height accounting for the search input height
  • Infima-compatible: Uses Docusaurus CSS variables (--ifm-*) for colors and spacing

Assets

  • assets/DocSidebar-index.tsx - Template for the swizzled DocSidebar component