adding search bar for navigation groups and items
- Published: 24 Mar 2025 Updated: 26 Mar 2025
 
when you have a lot of resources, let your users search for what they looking for int he sidebar.
                First: add the render hook in the panel provider:
1->renderHook(PanelsRenderHook::SIDEBAR_NAV_START, fn () => view('filament.components.navigation-filter'));
Next: create the view `navigation-filter.blade.php`:
 1<div
 2     @if (filament()->isSidebarCollapsibleOnDesktop())
 3        x-bind:class="$store.sidebar.isOpen ? 'block' : 'hidden'"
 4    @endif
 5>
 6    <x-filament::input.wrapper
 7        class="relative"
 8        :inline-prefix="true"
 9        prefix-icon="tabler-brand-finder"
10    >
11        <x-filament::input
12            type="text"
13            placeholder="search ..."
14            x-data="sidebarSearch()"
15            x-ref="search"
16            x-on:input.debounce.300ms="filterItems($event.target.value)"
17            x-on:keydown.escape="clearSearch"
18            x-on:keydown.meta.j.prevent.document="$refs.search.focus()"
19        />
20
21        <kbd class="absolute right-2 top-1/2 transform -translate-y-1/2 bg-gray-100 border border-gray-300 text-gray-400 dark:bg-gray-800 dark:border-gray-600 dark:text-gray-50 text-xs px-1.5 flex items-center justify-center gap-1 py-1 rounded-md">
22            @svg('tabler-command', 'h-4 w-4 text-gray-400')
23            <kd>J</kd>
24        </kbd>
25    </x-filament::input.wrapper>
26
27    <script>
28        document.addEventListener('alpine:init', () => {
29            Alpine.data('sidebarSearch', () => ({
30                init() {
31                    this.$refs.search.value = ''
32                },
33
34                filterItems(searchTerm) {
35                    const groups = document.querySelectorAll('.fi-sidebar-nav-groups .fi-sidebar-group')
36                    searchTerm = searchTerm.toLowerCase()
37
38                    groups.forEach(group => {
39                        const groupButton = group.querySelector('.fi-sidebar-group-button')
40                        const groupText = groupButton?.textContent.toLowerCase() || ''
41                        const items = group.querySelectorAll('.fi-sidebar-item')
42                        let hasVisibleItems = false
43
44                        const groupMatches = groupText.includes(searchTerm)
45
46                        items.forEach(item => {
47                            const itemText = item.textContent.toLowerCase()
48                            const isVisible = itemText.includes(searchTerm) || groupMatches
49
50                            item.style.display = isVisible ? '' : 'none'
51                            if (isVisible) hasVisibleItems = true
52                        })
53
54                        group.style.display = (hasVisibleItems || groupMatches) ? '' : 'none'
55                    })
56                },
57
58                clearSearch() {
59                    this.$refs.search.value = ''
60                    this.filterItems('')
61                }
62            }))
63        })
64    </script>
65</div>
take a look at the result in our demo app.
thanks to Azad Furkan ŞAKAR for the gist
    Related Tricks:
provide a loading indicator for long running operations
Usability: Knowing whether or not the record was saved.
how to use an action as a headerAction or as a table row action without code duplication
add any link or actions to the topbar
How to Apply Authorization on Create Option Action for Select Field