Quick start
Add a fully featured command bar to your app in five minutes.
This guide builds a command bar with routes, commands, live search and a form. It takes about five minutes.
1. Create the bar
Call createQikbar once, on the client:
import { createQikbar } from '@qikbar/qikbar'
export const bar = createQikbar({
placeholder: 'Search or jump to…',
})
Press ⌘K. The bar is empty, so let’s fill it.
Using React? Render <Qikbar /> from @qikbar/qikbar/react instead. It takes the same options as props. See React.
2. Add routes
Routes are pages in your app. Pass your router’s navigate function so navigation stays client-side:
createQikbar({
navigate: (href) => router.push(href),
routes: [
{ path: '/', title: 'Dashboard', icon: 'home' },
{ path: '/projects', title: 'Projects', icon: 'folder' },
{ path: '/settings/billing', title: 'Billing', icon: 'credit-card', keywords: ['invoice', 'plan'] },
],
})
If you don’t pass navigate, Qikbar clicks a matching link on the page, which works with most routers. Otherwise it does a normal navigation. See Routing.
3. Add commands
Commands run code. Group them with section and give them global shortcuts:
commands: [
{ title: 'New project', icon: 'plus', section: 'Projects', shortcut: 'c p', run: () => openNewProjectDialog() },
{ title: 'Toggle sidebar', icon: 'layout-dashboard', shortcut: 'mod+b', run: () => toggleSidebar() },
{ title: 'Sign out', icon: 'log-out', run: () => signOut() },
]
shortcut: 'c p' means press C then P, anywhere in your app.
4. Search your data
A source searches your API as the user types. Qikbar debounces the calls, cancels stale requests, and merges the results into their own section:
sources: [
{
id: 'projects',
title: 'Projects',
async search({ query, signal }) {
const res = await fetch(`/api/projects?q=${encodeURIComponent(query)}`, { signal })
const projects = await res.json()
return projects.map((p) => ({
title: p.name,
subtitle: p.owner,
icon: 'folder',
href: `/projects/${p.id}`,
}))
},
},
]
5. Push a view
Commands can open views: lists, grids, Markdown details, forms and AI chats. Here’s a form:
import { form } from '@qikbar/qikbar'
commands: [
{
title: 'Invite teammate',
icon: 'users',
view: form({
title: 'Invite teammate',
fields: [
{ name: 'email', label: 'Email', type: 'email', required: true },
{ name: 'role', label: 'Role', type: 'select', options: [{ title: 'Member', value: 'member' }, { title: 'Admin', value: 'admin' }] },
],
async onSubmit(values, ctx) {
await api.invite(values)
ctx.toast({ title: `Invited ${values.email}`, style: 'success' })
},
}),
},
]
6. Add extensions
import { calculator, themeSwitcher, shortcuts } from '@qikbar/qikbar/extensions'
createQikbar({
// …
extensions: [calculator(), themeSwitcher(), shortcuts()],
})
Now typing 12 * 7 or 5 km in mi shows the answer instantly.
7. Make it yours
Pick a theme preset or match your design tokens:
createQikbar({
theme: { preset: 'linear', vars: { accent: 'var(--brand)', radius: '10px', font: 'inherit' } },
})
8. Optional: AI
import { proxy } from '@qikbar/qikbar'
createQikbar({ ai: proxy('/api/qikbar') })
Users can now press Tab to ask AI, and the model can run your commands. See AI to set up the server route.
Add a trigger button
Any element with data-qikbar-open opens the bar:
<button data-qikbar-open>Search… <kbd>⌘K</kbd></button>
Or call bar.open().