Skip to main content
Get started with Svelte Drawer by building a basic bottom drawer. This guide will have you up and running in minutes.

Basic Setup

1

Import Components

Import the essential drawer components into your Svelte file:
<script>
  import { 
    Drawer, 
    DrawerOverlay, 
    DrawerContent, 
    DrawerHandle 
  } from '@abhivarde/svelte-drawer';
</script>
2

Create State

Use Svelte 5’s $state rune to manage the drawer’s open/closed state:
<script>
  import { 
    Drawer, 
    DrawerOverlay, 
    DrawerContent, 
    DrawerHandle 
  } from '@abhivarde/svelte-drawer';

  let open = $state(false);
</script>
Svelte Drawer is built for Svelte 5 and uses the new runes syntax. The $state rune creates reactive state.
3

Add Trigger Button

Create a button to open the drawer:
<script>
  import { 
    Drawer, 
    DrawerOverlay, 
    DrawerContent, 
    DrawerHandle 
  } from '@abhivarde/svelte-drawer';

  let open = $state(false);
</script>

<button onclick={() => open = true}>
  Open Drawer
</button>
4

Build the Drawer

Add the drawer structure with overlay, content, and handle:
<script>
  import { 
    Drawer, 
    DrawerOverlay, 
    DrawerContent, 
    DrawerHandle 
  } from '@abhivarde/svelte-drawer';

  let open = $state(false);
</script>

<button onclick={() => open = true}>
  Open Drawer
</button>

<Drawer bind:open>
  <DrawerOverlay class="fixed inset-0 bg-black/40" />
  <DrawerContent class="fixed bottom-0 left-0 right-0 bg-white rounded-t-lg p-4">
    <DrawerHandle class="mb-8" />
    <h2>Drawer Content</h2>
    <p>This is a drawer component.</p>
    <button onclick={() => open = false}>Close</button>
  </DrawerContent>
</Drawer>
The bind:open directive creates a two-way binding, allowing the drawer to update the state when dismissed via gestures or the Escape key.

Complete Example

Here’s the complete code for a working drawer:
<script>
  import { 
    Drawer, 
    DrawerOverlay, 
    DrawerContent, 
    DrawerHandle 
  } from '@abhivarde/svelte-drawer';

  let open = $state(false);
</script>

<button onclick={() => open = true}>
  Open Drawer
</button>

<Drawer bind:open>
  <DrawerOverlay class="fixed inset-0 bg-black/40" />
  <DrawerContent class="fixed bottom-0 left-0 right-0 bg-white rounded-t-lg p-4">
    <DrawerHandle class="mb-8" />
    <h2>Drawer Content</h2>
    <p>This is a drawer component.</p>
    <button onclick={() => open = false}>Close</button>
  </DrawerContent>
</Drawer>

Understanding the Components

The main wrapper component that manages state, animations, and gesture handling. Use bind:open to control visibility.
The semi-transparent backdrop that appears behind the drawer. Clicking it dismisses the drawer.
The container for your drawer content. Includes drag detection and focus management.
The visual drag indicator at the top of the drawer. Provides a clear affordance for gesture interactions.

Try Different Directions

The drawer can slide from any edge of the screen:
<Drawer bind:open>
  <DrawerOverlay class="fixed inset-0 bg-black/40" />
  <DrawerContent class="fixed bottom-0 left-0 right-0 bg-white rounded-t-lg p-4">
    <DrawerHandle class="mb-8" />
    <h2>Bottom Drawer</h2>
  </DrawerContent>
</Drawer>

What’s Next?

Now that you have a basic drawer working, explore more advanced features:

Variants

Use prebuilt variants like sheet, dialog, and sidebar

Snap Points

Create iOS-like drawers with multiple snap positions

Styling & Blur

Customize appearance and add blur effects to overlays

Portal Rendering

Escape z-index conflicts with portal rendering

Build docs developers (and LLMs) love