Best for
Founders who want a keyboard-navigable command palette or spotlight search for their SaaS app
Stack
A ready-made Action Search Bar UI you can fork, run, and customize with the prompt pack below.
What's actually inside
The honest engineer's breakdown — what the Action Search Bartemplate does, how it's wired, and where it's opinionated.
The Action Search Bar template is a Cmd+K command palette — the same interaction pattern used by Linear, Vercel, and Raycast. The CommandDialog wraps shadcn/ui's cmdk primitives in a centered overlay that opens as a portal, keeping it visually above all page content. The SearchInput inside is auto-focused on open and wired to cmdk's built-in filtering, so results narrow in real-time as you type without any extra state management.
Results are organized into named CommandGroup sections (e.g., Pages, Actions, Recent) populated by CommandItem rows, each showing an icon, label, and optional keyboard shortcut badge. The EmptyState component renders 'No results found' when cmdk's filter returns nothing — a small but important UX detail. Framer Motion handles the dialog's open/close spring animation so the overlay feels snappy rather than abrupt.
Honest caveat: the default template ships with hardcoded CommandGroup items — there is no API wiring out of the box. The search filtering is entirely client-side, which is fast for small datasets but won't scale to thousands of records. If you need localStorage recent searches, that too requires a useEffect guard (reading localStorage in the component body will throw during SSR). Both patterns are covered in the prompts below.
Key UI components
CommandDialog wrappershadcn/ui's <CommandDialog> (powered by cmdk) that opens as a centered overlay portal
SearchInputControlled text input inside the dialog, auto-focused on open, wired to cmdk filtering
CommandListScrollable result list with keyboard arrow-key navigation
CommandGroupLabeled sections grouping results (e.g., Pages, Recent, Actions)
CommandItemIndividual selectable rows with icon, label, and optional keyboard shortcut badge
EmptyState'No results found' fallback rendered when cmdk finds no matches
Libraries it leans on
cmdkHeadless command palette — handles filtering, keyboard navigation, and selection
shadcn/uiCommand primitives (CommandDialog, CommandList, CommandGroup, CommandItem) built on cmdk
Framer MotionDialog open/close spring animation (scale + opacity)
Tailwind CSSLayout, typography, color scheme for the overlay and list items
Fork it and get it running
Forking takes about five minutes in the browser. You can have the command palette live on Vercel before you've written a single line of your own code.
Open the community page and fork
Go to https://v0.dev/chat/community/S3nMPSmpQzk in your browser. Click Fork in the top-right corner. V0 clones the project into your account and opens the editor with the Vercel Sandbox preview on the right.
Tip: You need a free v0.dev account to fork. Sign up at v0.dev if you haven't already.
You should see: V0 editor opens with the Action Search Bar project. The preview pane shows a page with a visible trigger button or Cmd+K hint.
Test keyboard navigation in the preview
In the Vercel Sandbox preview pane, press Cmd+K (Mac) or click the trigger button shown in the demo to open the CommandDialog. Use the arrow keys to navigate between CommandItem rows and press Enter to select one — confirm the dialog closes. Press Escape to dismiss without selecting. This confirms cmdk's keyboard handling is working before you edit anything.
Tip: The Cmd+K shortcut may not fire in the V0 editor's own UI — click the trigger button in the preview iframe instead.
You should see: CommandDialog opens, arrow keys move selection, Enter selects, Escape closes — all without clicking.
Replace the placeholder CommandGroup items
In the Code tab, find the hardcoded CommandGroup array (an array of objects with label, icon, and onSelect fields) and replace the example items with your app's actual pages, actions, and settings routes. This is a direct code edit in the editor — no V0 credits consumed. Update the CommandGroup headings to match: 'Pages', 'Actions', 'Settings'.
You should see: The preview now shows your app's real navigation items inside the CommandDialog.
Publish to production
Click Share in the top-right, then open the Publish tab and click 'Publish to Production'. V0 deploys in under 60 seconds to a Vercel subdomain. The live URL works immediately — no additional configuration needed for the static command palette.
You should see: A live Vercel URL is displayed. Opening it shows the command palette trigger on a real deployed page.
Connect GitHub for version control
Open the Git panel in V0's left sidebar and click Connect GitHub. Authorize V0 to access your GitHub account, then choose or create a repository. V0 auto-creates a branch (v0/main-abc123) and opens a pull request. Merge the PR to sync the project code to your main branch.
Tip: V0 never pushes directly to your main branch — always creates a PR for you to review first.
You should see: Your GitHub repo contains the Action Search Bar code and all future V0 edits will sync via pull requests.
The prompt pack
Copy-paste these straight into v0's chat to customize the Action Search Bartemplate. Each one names this template's own components — no generic filler.
Rebrand the CommandDialog with my app's copy and colors
Updates placeholder text, brand border color, and CommandGroup labels without touching any cmdk or Framer Motion logic.
Update the SearchInput placeholder text inside the CommandDialog to 'Search pages, actions, and settings…'. Change the CommandDialog border to use my brand color via Tailwind's border-violet-500 class. Update all CommandGroup headings to: 'Pages', 'Actions', 'Settings'. Keep all keyboard navigation behavior (arrow keys, Enter to select, Esc to close) and the Framer Motion spring animation unchanged.
Add a global Cmd+K keyboard shortcut to open the dialog
Wires a global keyboard shortcut so the CommandDialog opens from any page without needing a visible trigger button.
Add a global keyboard listener so that pressing Cmd+K (Mac) or Ctrl+K (Windows/Linux) opens the CommandDialog from anywhere in the app. Implement this with a useEffect that adds a window keydown event listener — check for event.metaKey || event.ctrlKey and event.key === 'k', then call setOpen(true) and event.preventDefault(). Esc to dismiss is already handled by cmdk automatically and should be left unchanged.
Load CommandList results from a Next.js API route with Supabase
Replaces hardcoded CommandGroup items with a live Supabase-backed search — results update as the user types in the SearchInput.
Replace the hardcoded CommandList items with dynamic results fetched from GET /api/search?q={query}. Call this route handler every time the CommandInput value changes, debounced by 200ms using a setTimeout cleared on each new keystroke. The route handler should query a Supabase table called pages with columns title, slug, and description using a ILIKE '%query%' filter. Render each matching row as a CommandItem that navigates to /pages/[slug] on selection using Next.js router.push().Add recent searches with localStorage persistence
Adds a persistent Recent CommandGroup showing the last 5 queries, stored in localStorage and safely loaded after mount.
Add a 'Recent' CommandGroup that shows the last 5 search queries the user has run in the CommandDialog. Store the history in localStorage under the key 'action-search-history' as a JSON array of strings. On each CommandItem selection, prepend the current query to the history array (deduplicate, keep max 5 items) and save back to localStorage. On dialog open, read history from localStorage inside a useEffect — do not read it during server render to avoid Next.js SSR errors.
Filter CommandDialog results by Supabase user role
Adds role-based visibility to CommandList results — admin-only actions are hidden or replaced with an access message for other roles.
Fetch the current user's role from Supabase Auth using supabase.auth.getUser() inside a Server Action called getSearchPermissions(). Pass the role as a prop to the CommandDialog client component. Filter CommandItem entries client-side: items with requiredRole: 'admin' should be hidden from the CommandList unless the user's role is 'admin'. For non-admin users, show a disabled CommandItem labeled 'Contact your admin to access this' in place of the hidden items, with pointer-events-none and opacity-50 styling.
Gotchas when you extend it
The failures people actually hit when they push this template past its defaults — and the exact fix for each.
Module not found: Error: Can't resolve '@/components/ui/command'Why: When forking to a local Next.js project or importing via GitHub, the shadcn Command component may not be installed — V0 assumes it exists, but your project's components.json may differ.
Fix: Run npx shadcn add command in your local terminal to install the component, or prompt V0 to add it before exporting.
Add the shadcn/ui command component to this project by running npx shadcn add command and fixing any import path errors in the CommandDialog usage.
Framer Motion spring animation causes layout shift on CommandDialog openWhy: The overlay animation briefly renders outside the viewport bounds before settling, causing a visible content jump — especially on mobile viewport widths.
Fix: Add overflow-hidden to the dialog container and set initial={{ opacity: 0, scale: 0.95 }} animate={{ opacity: 1, scale: 1 }} with a tight spring ({ stiffness: 300, damping: 30 }) to prevent the jump.
Fix the layout shift when CommandDialog opens — add overflow-hidden to the dialog container and use a scale+opacity spring animation with stiffness 300, damping 30 instead of the current animation.
Tailwind v3/v4 conflict: classes not applying after local cloneWhy: V0 generates Tailwind v3.4 classes (e.g., ring-offset-background), but create-next-app defaults to Tailwind v4 which removed tailwind.config.js — the CommandDialog loses its border, backdrop, and ring styles.
Fix: Check your local Tailwind version with npx tailwindcss --version. If v4, prompt V0 to update all Tailwind v3 utility classes to v4 CSS-based config syntax.
This project has a Tailwind v3/v4 version mismatch — update tailwind.config.js and all CSS utilities to be compatible with Tailwind v4.2.
ReferenceError: localStorage is not defined (on recent searches feature)Why: Any code reading localStorage inside the component body (not inside useEffect) runs during SSR in Next.js App Router and throws during server rendering or static generation.
Fix: Always initialize state as an empty array, then sync from localStorage inside useEffect(() => { setHistory(JSON.parse(localStorage.getItem('action-search-history') || '[]')) }, []).
Fix the localStorage SSR error — move all localStorage reads into a useEffect with an empty dependency array and initialize the history state with an empty array.
Template vs. custom — the honest call
A forked template gets you far, fast. Here's where it holds up, and where you'll outgrow it.
The template is enough when
- You want a Cmd+K palette for page navigation and quick actions in a SaaS dashboard
- Your dataset is small enough to filter client-side or with a simple ILIKE API query
- You need this shipped in a day without custom search architecture
- You're building a SaaS app and need the standard power-user keyboard shortcut
Go custom when
- You need full-text search across large datasets — Postgres full-text or Algolia with relevance ranking is out of scope here
- You need search history synced across devices, which requires a backend session store rather than localStorage
- You need voice input or AI-powered semantic search with embedding-based retrieval
Need the Action Search Bar wired to a real database with role-based result filtering? RapidDev can extend this V0 template into a production-ready search layer.
Frequently asked questions
Is the Action Search Bar v0 template free to use?
Yes. V0 community templates are free to fork. You need a free v0.dev account — forking does not consume any credits. The cmdk library and shadcn/ui Command primitives are both MIT-licensed.
Can I use this command palette in a commercial SaaS product?
Yes. The generated V0 code is yours to use in any product, commercial or otherwise. cmdk and shadcn/ui are MIT-licensed with no royalty or attribution requirements for end products.
Why does my CommandDialog look broken or unstyled after cloning locally?
The most common cause is a Tailwind version mismatch. V0 generates Tailwind v3.4 classes (like ring-offset-background) but create-next-app now defaults to Tailwind v4, which dropped tailwind.config.js. Also check that the shadcn/ui Command component is installed in your local project — run npx shadcn add command if it's missing.
How do I make the Cmd+K shortcut work on Windows?
Use event.metaKey || event.ctrlKey in your keydown listener — event.metaKey is true on Mac for the Cmd key, event.ctrlKey is true on Windows and Linux for Ctrl. Both map to the same shortcut pattern. The medium prompt above implements this correctly.
Why does my fork break in V0 preview after adding a recent searches feature?
localStorage is not available during server-side rendering in Next.js App Router. If you read localStorage in the component body (outside a useEffect), the SSR pass throws ReferenceError: localStorage is not defined. Always initialize your history state as an empty array and read localStorage inside a useEffect with an empty dependency array.
How do I connect the search to a real database?
Create a Next.js route handler at app/api/search/route.ts that accepts a query parameter and runs an ILIKE filter against your Supabase table. The medium prompt in the pack above gives you the complete implementation — paste it into the V0 chat and it handles the debounce, fetch, and CommandItem rendering.
Can RapidDev build a production search layer on top of this template?
Yes. If you need the command palette wired to a full-text search engine, role-based result filtering, or cross-device history sync, RapidDev can scope and deliver that as a production engagement on top of this V0 prototype.
Does this template work with the Vercel AI SDK for semantic search?
Not out of the box, but it's a reasonable extension. You'd replace the /api/search route handler with one that generates an embedding for the query, runs a vector similarity search against a pgvector column in Supabase, and returns ranked results as CommandItems. That's an advanced customization not covered by this template's built-in prompts.
Outgrowing the template?
RapidDev turns v0 prototypes into production apps — real auth, database, and payments — at $13K–$25K.
Book a free consultation30-min call. No commitment.