Let's add a Command Palette on our website

2/4/2022 -- views min read


Before you start, let’s see what we are going to build.

Try it out – press cmd+k (macOS) or ctrl+k (Linux/Windows), or click the CMD icon in the header above.

Awesome! Now let’s start.

All the code used in this blog is available on this CodeSandbox Link. CSB LINK

We will be using a library called KBar


Adding Provider and actions

In your root file, wrap the App with a KbarProvider and pass it the default actions prop

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 // index.js import { KBarProvider } from 'kbar' const actions = [ { id: 'youtube', name: 'Youtube', shortcut: ['g', 'y'], perform: () => (window.location.href = 'https://www.youtube.com/watch?v=dQw4w9WgXcQ') }, { id: 'twitter', name: 'Twitter', shortcut: ['g', 't'], keywords: 'twitter', perform: () => (window.location.href = 'https://twitter.com/verma__shubham') } ] return ( <KBarProvider actions={actions}> <App /> </KBarProvider> )

Now if you press the shortcut, you will see that nothing happens. This is because we haven’t added the other utilities that Kbar provides.


Adding KBar utilities

Let’s add the below code.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 // index.js import { KBarAnimator, KBarPortal, KBarPositioner, KBarProvider, KBarResults, KBarSearch } from 'kbar' const actions = [ //... ] return ( <KBarProvider actions={actions}> <KBarPortal> <KBarPositioner> <KBarAnimator> <KBarSearch /> </KBarAnimator> </KBarPositioner> </KBarPortal> <App /> </KBarProvider> )

Now we are able to see a search box when you press the shortcut! But you’ll notice nothing happens when we search.

Why are our default actions not rendered?

Adding the KBarResults

  • Create a component called Results.
  • The useMatches() hooks returns us the results of the searched query.
  • We will use the KBarResults component to render the results.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 const Results = () => { const { results } = useMatches() return ( <KBarResults items={results} onRender={({ item, active }) => { return typeof item === 'string' ? ( // For sections. <div> {item}</div> ) : ( // For the items. <p style={{ backgroundColor: active ? 'gray' : 'white', height: '50px' }} > {item.name} </p> ) }} /> ) } // USE THE ABOVE COMPONENT right after the KBarSearch /> // ... ;<KBarProvider> <KBarPortal> <KBarPositioner> <KBarAnimator> <KBarSearch /> {/* USE THE Results COMPONENT here*/} <Results /> </KBarAnimator> </KBarPositioner> </KBarPortal> <App /> </KBarProvider> // ...

Adding nested Results

If you open up Kbar on this website, you will see a “Search Blogs” item which opens up nested results. Let’s see how its done.

  • All we need to do it add a action and reference the other actions with a parent key.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 // Change the actions variable to this const actions = [ { id: 'youtube', name: 'Youtube', shortcut: ['g', 'y'], perform: () => (window.location.href = 'https://www.youtube.com/watch?v=dQw4w9WgXcQ') }, { id: 'twitter', name: 'Twitter', shortcut: ['g', 't'], keywords: 'twitter', perform: () => (window.location.href = 'https://twitter.com/verma__shubham') }, { id: 'search-blogs', name: 'Search Blogs', shortcut: ['s', 'b'] }, { id: 'blog-1', name: 'Blog 1', parent: 'search-blogs' }, { id: 'blog-2', name: 'Blog 2', parent: 'search-blogs' } ]

Toggling KBar using the useKar hook

In our App.js file, we will use the useKBar() hook to toggle KBar.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 import { useKBar } from 'kbar' import './styles.css' export default function App() { const kbar = useKBar() return ( <div className='App'> <h1>Hit Ctrl + K or Cmd + K</h1> <button onClick={() => { kbar.query.toggle() }} > Toggle Kbar </button> </div> ) }

That's it! Now you can toggle KBar by pressing Cmd + K on macOS

or Ctrl+K on Windows/Linux. And also by clicking the CMD icon button.


My Socials


Found this blog helpful? Share it with your friends!