Custom Components

Extend the command palette with custom empty states, icons, and grouped actions.

Custom Empty State

Provide a custom UI when no search results are found:

Custom Empty State
<script lang="ts">
  import CommandPalette, { defineActions } from '$lib';
</script>

<CommandPalette commands={actions}>
  {#snippet emptyState()}
    <div class="custom-empty">
      <svg width="48" height="48" viewBox="0 0 24 24" fill="none" stroke="currentColor">
        <circle cx="11" cy="11" r="8"/>
        <path d="m21 21-4.3-4.3"/>
      </svg>
      <h3>No results found</h3>
      <p>Try searching for something else</p>
      <button on:click={() => console.log('Create new')}>
        Create new action
      </button>
    </div>
  {/snippet}
</CommandPalette>

Action Icons

Add visual icons to your actions using emojis or image URLs:

Icon Types
const actions = defineActions([
  // Emoji icons
  {
    title: 'Settings',
    icon: '⚙️',
    onRun: () => openSettings()
  },
  
  // Image URL icons
  {
    title: 'GitHub',
    icon: 'https://github.githubassets.com/favicons/favicon.svg',
    onRun: () => window.open('https://github.com')
  },
  
  // Local image icons
  {
    title: 'Profile',
    icon: '/icons/user.svg',
    onRun: () => openProfile()
  }
]);
🚀

Emoji

Simple and universal

GitHub

URL

External images

📁

Local

Static assets

Snippet

Custom SVG/Components

Using Icon Libraries (Lucide, Heroicons, etc.)

For professional-looking icons, use third-party libraries like Lucide, Heroicons, or any Svelte icon library. Define your icons as Snippets and pass them to the icon property:

Using Lucide Icons
<script lang="ts">
  import CommandPalette, { defineActions } from 'svelte-command-palette';
  import { Settings, Search, User, Home, FolderPlus, Download } from 'lucide-svelte';
</script>

<!-- Define snippets for each icon -->
{#snippet settingsIcon()}
  <Settings size={20} />
{/snippet}

{#snippet searchIcon()}
  <Search size={20} />
{/snippet}

{#snippet userIcon()}
  <User size={20} />
{/snippet}

{#snippet homeIcon()}
  <Home size={20} />
{/snippet}

<!-- Use snippets in your actions -->
<script>
  const actions = defineActions([
    {
      title: 'Open Settings',
      subTitle: 'Configure your preferences',
      icon: settingsIcon,
      onRun: () => goto('/settings')
    },
    {
      title: 'Search Files',
      subTitle: 'Find files in your project',
      icon: searchIcon,
      onRun: () => openSearch()
    },
    {
      title: 'View Profile',
      subTitle: 'See your account details',
      icon: userIcon,
      onRun: () => goto('/profile')
    },
    {
      title: 'Go Home',
      subTitle: 'Return to dashboard',
      icon: homeIcon,
      onRun: () => goto('/')
    }
  ]);
</script>

<CommandPalette commands={actions} />

Live Demo

Here's how Lucide icons look in practice:

Settings
Search
User
Home
FolderPlus
Download
📦
Install Lucide: npm install lucide-svelte

Action Groups

Organize related actions under group headers:

Grouped Actions
const actions = defineActions([
  // Navigation group
  {
    title: 'Go to Dashboard',
    group: 'Navigation',
    icon: '🏠',
    onRun: () => goto('/dashboard')
  },
  {
    title: 'Go to Settings',
    group: 'Navigation', 
    icon: '⚙️',
    onRun: () => goto('/settings')
  },
  
  // Actions group
  {
    title: 'Create New Project',
    group: 'Actions',
    icon: '➕',
    onRun: () => createProject()
  },
  {
    title: 'Export Data',
    group: 'Actions',
    icon: '📤',
    onRun: () => exportData()
  },
  
  // Ungrouped items appear at the top
  {
    title: 'Quick Search',
    icon: '🔍',
    onRun: () => quickSearch()
  }
]);
💡
Tip: Actions without a group property appear at the top of the list. Groups are displayed in the order they first appear in your actions array.