---
title: Context Menu
description: Displays a menu located at the pointer, triggered by a right click or a long press.
---

```templ
package examples

import "github.com/axadrn/shadcn-templ/v2/components/contextmenu"

templ ContextMenuDemo() {
	@contextmenu.ContextMenu() {
		@contextmenu.Trigger(contextmenu.TriggerProps{Class: "flex aspect-video w-full max-w-xs items-center justify-center rounded-xl border border-dashed text-sm"}) {
			<span class="hidden pointer-fine:inline-block">Right click here</span>
			<span class="hidden pointer-coarse:inline-block">Long press here</span>
		}
		@contextmenu.Content(contextmenu.ContentProps{Class: "w-48"}) {
			@contextmenu.Group() {
				@contextmenu.Item() {
					Back
					@contextmenu.Shortcut() {
						⌘[
					}
				}
				@contextmenu.Item(contextmenu.ItemProps{Disabled: true}) {
					Forward
					@contextmenu.Shortcut() {
						⌘]
					}
				}
				@contextmenu.Item() {
					Reload
					@contextmenu.Shortcut() {
						⌘R
					}
				}
				@contextmenu.Sub() {
					@contextmenu.SubTrigger() {
						More Tools
					}
					@contextmenu.SubContent(contextmenu.SubContentProps{Class: "w-44"}) {
						@contextmenu.Group() {
							@contextmenu.Item() {
								Save Page...
							}
							@contextmenu.Item() {
								Create Shortcut...
							}
							@contextmenu.Item() {
								Name Window...
							}
						}
						@contextmenu.Separator()
						@contextmenu.Group() {
							@contextmenu.Item() {
								Developer Tools
							}
						}
						@contextmenu.Separator()
						@contextmenu.Group() {
							@contextmenu.Item(contextmenu.ItemProps{Variant: contextmenu.ItemVariantDestructive}) {
								Delete
							}
						}
					}
				}
			}
			@contextmenu.Separator()
			@contextmenu.Group() {
				@contextmenu.CheckboxItem(contextmenu.CheckboxItemProps{Checked: true}) {
					Show Bookmarks
				}
				@contextmenu.CheckboxItem() {
					Show Full URLs
				}
			}
			@contextmenu.Separator()
			@contextmenu.Group() {
				@contextmenu.RadioGroup() {
					@contextmenu.Label() {
						People
					}
					@contextmenu.RadioItem(contextmenu.RadioItemProps{Value: "pedro", Checked: true}) {
						Pedro Duarte
					}
					@contextmenu.RadioItem(contextmenu.RadioItemProps{Value: "colm"}) {
						Colm Tuite
					}
				}
			}
		}
	}
}
```

## Installation

<CodeTabs>

<TabsList>
  <TabsTrigger value="cli">Command</TabsTrigger>
  <TabsTrigger value="manual">Manual</TabsTrigger>
</TabsList>
<TabsContent value="cli">

```bash
shadcn-templ add context-menu
```

</TabsContent>

<TabsContent value="manual">

<Steps className="mb-0 pt-2">

<Step>Copy and paste the following code into your project.</Step>

<ComponentSource name="context-menu" title="components/contextmenu/contextmenu.templ" />

<ComponentSource name="context-menu" title="components/contextmenu/contextmenu.js" />

<ComponentSource name="context-menu" title="components/floatingui/floating_ui_core.js" />

<ComponentSource name="context-menu" title="components/floatingui/floating_ui_dom.js" />

Component scripts are loaded through the shared script bundle, see [JavaScript](/docs/installation#javascript).

<Step>Update the import paths to match your project setup.</Step>

</Steps>

</TabsContent>

</CodeTabs>

## Usage

```go showLineNumbers
import "github.com/axadrn/shadcn-templ/v2/components/contextmenu"
```

```templ showLineNumbers
@contextmenu.ContextMenu() {
	@contextmenu.Trigger() {
		Right click here
	}
	@contextmenu.Content() {
		@contextmenu.Item() {
			Profile
		}
		@contextmenu.Item() {
			Billing
		}
		@contextmenu.Item() {
			Team
		}
		@contextmenu.Item() {
			Subscription
		}
	}
}
```

## Composition

Use the following composition to build a `ContextMenu`:

```text
contextmenu.ContextMenu
├── contextmenu.Trigger
└── contextmenu.Content
    ├── contextmenu.Group
    │   ├── contextmenu.Label
    │   ├── contextmenu.Item
    │   └── contextmenu.Item
    ├── contextmenu.Separator
    ├── contextmenu.Group
    │   ├── contextmenu.Label
    │   ├── contextmenu.CheckboxItem
    │   └── contextmenu.CheckboxItem
    ├── contextmenu.Separator
    ├── contextmenu.Group
    │   ├── contextmenu.Label
    │   └── contextmenu.RadioGroup
    │       ├── contextmenu.RadioItem
    │       └── contextmenu.RadioItem
    └── contextmenu.Sub
        ├── contextmenu.SubTrigger
        └── contextmenu.SubContent
            └── contextmenu.Group
                ├── contextmenu.Item
                └── contextmenu.Item
```

## Basic

A simple context menu with a few actions.

```templ
package examples

import "github.com/axadrn/shadcn-templ/v2/components/contextmenu"

templ ContextMenuBasic() {
	@contextmenu.ContextMenu() {
		@contextmenu.Trigger(contextmenu.TriggerProps{Class: "flex aspect-video w-full max-w-xs items-center justify-center rounded-xl border border-dashed text-sm"}) {
			<span class="hidden pointer-fine:inline-block">Right click here</span>
			<span class="hidden pointer-coarse:inline-block">Long press here</span>
		}
		@contextmenu.Content() {
			@contextmenu.Group() {
				@contextmenu.Item() {
					Back
				}
				@contextmenu.Item(contextmenu.ItemProps{Disabled: true}) {
					Forward
				}
				@contextmenu.Item() {
					Reload
				}
			}
		}
	}
}
```

## Submenu

Use `contextmenu.Sub` to nest secondary actions.

```templ
package examples

import "github.com/axadrn/shadcn-templ/v2/components/contextmenu"

templ ContextMenuSubmenu() {
	@contextmenu.ContextMenu() {
		@contextmenu.Trigger(contextmenu.TriggerProps{Class: "flex aspect-video w-full max-w-xs items-center justify-center rounded-xl border border-dashed text-sm"}) {
			<span class="hidden pointer-fine:inline-block">Right click here</span>
			<span class="hidden pointer-coarse:inline-block">Long press here</span>
		}
		@contextmenu.Content() {
			@contextmenu.Group() {
				@contextmenu.Item() {
					Copy
					@contextmenu.Shortcut() {
						⌘C
					}
				}
				@contextmenu.Item() {
					Cut
					@contextmenu.Shortcut() {
						⌘X
					}
				}
			}
			@contextmenu.Sub() {
				@contextmenu.SubTrigger() {
					More Tools
				}
				@contextmenu.SubContent() {
					@contextmenu.Group() {
						@contextmenu.Item() {
							Save Page...
						}
						@contextmenu.Item() {
							Create Shortcut...
						}
						@contextmenu.Item() {
							Name Window...
						}
					}
					@contextmenu.Separator()
					@contextmenu.Group() {
						@contextmenu.Item() {
							Developer Tools
						}
					}
					@contextmenu.Separator()
					@contextmenu.Group() {
						@contextmenu.Item(contextmenu.ItemProps{Variant: contextmenu.ItemVariantDestructive}) {
							Delete
						}
					}
				}
			}
		}
	}
}
```

## Shortcuts

Add `contextmenu.Shortcut` to show keyboard hints.

```templ
package examples

import "github.com/axadrn/shadcn-templ/v2/components/contextmenu"

templ ContextMenuShortcuts() {
	@contextmenu.ContextMenu() {
		@contextmenu.Trigger(contextmenu.TriggerProps{Class: "flex aspect-video w-full max-w-xs items-center justify-center rounded-xl border border-dashed text-sm"}) {
			<span class="hidden pointer-fine:inline-block">Right click here</span>
			<span class="hidden pointer-coarse:inline-block">Long press here</span>
		}
		@contextmenu.Content() {
			@contextmenu.Group() {
				@contextmenu.Item() {
					Back
					@contextmenu.Shortcut() {
						⌘[
					}
				}
				@contextmenu.Item(contextmenu.ItemProps{Disabled: true}) {
					Forward
					@contextmenu.Shortcut() {
						⌘]
					}
				}
				@contextmenu.Item() {
					Reload
					@contextmenu.Shortcut() {
						⌘R
					}
				}
			}
			@contextmenu.Separator()
			@contextmenu.Group() {
				@contextmenu.Item() {
					Save
					@contextmenu.Shortcut() {
						⌘S
					}
				}
				@contextmenu.Item() {
					Save As...
					@contextmenu.Shortcut() {
						⇧⌘S
					}
				}
			}
		}
	}
}
```

## Groups

Group related actions and separate them with dividers.

```templ
package examples

import "github.com/axadrn/shadcn-templ/v2/components/contextmenu"

templ ContextMenuGroups() {
	@contextmenu.ContextMenu() {
		@contextmenu.Trigger(contextmenu.TriggerProps{Class: "flex aspect-video w-full max-w-xs items-center justify-center rounded-xl border border-dashed text-sm"}) {
			<span class="hidden pointer-fine:inline-block">Right click here</span>
			<span class="hidden pointer-coarse:inline-block">Long press here</span>
		}
		@contextmenu.Content() {
			@contextmenu.Group() {
				@contextmenu.Label() {
					File
				}
				@contextmenu.Item() {
					New File
					@contextmenu.Shortcut() {
						⌘N
					}
				}
				@contextmenu.Item() {
					Open File
					@contextmenu.Shortcut() {
						⌘O
					}
				}
				@contextmenu.Item() {
					Save
					@contextmenu.Shortcut() {
						⌘S
					}
				}
			}
			@contextmenu.Separator()
			@contextmenu.Group() {
				@contextmenu.Label() {
					Edit
				}
				@contextmenu.Item() {
					Undo
					@contextmenu.Shortcut() {
						⌘Z
					}
				}
				@contextmenu.Item() {
					Redo
					@contextmenu.Shortcut() {
						⇧⌘Z
					}
				}
			}
			@contextmenu.Separator()
			@contextmenu.Group() {
				@contextmenu.Item() {
					Cut
					@contextmenu.Shortcut() {
						⌘X
					}
				}
				@contextmenu.Item() {
					Copy
					@contextmenu.Shortcut() {
						⌘C
					}
				}
				@contextmenu.Item() {
					Paste
					@contextmenu.Shortcut() {
						⌘V
					}
				}
			}
			@contextmenu.Separator()
			@contextmenu.Group() {
				@contextmenu.Item(contextmenu.ItemProps{Variant: contextmenu.ItemVariantDestructive}) {
					Delete
					@contextmenu.Shortcut() {
						⌫
					}
				}
			}
		}
	}
}
```

## Icons

Combine icons with labels for quick scanning.

```templ
package examples

import (
	"github.com/axadrn/shadcn-templ/v2/components/contextmenu"
	"github.com/axadrn/shadcn-templ/v2/components/icon"
)

templ ContextMenuIcons() {
	@contextmenu.ContextMenu() {
		@contextmenu.Trigger(contextmenu.TriggerProps{Class: "flex aspect-video w-full max-w-xs items-center justify-center rounded-xl border border-dashed text-sm"}) {
			<span class="hidden pointer-fine:inline-block">Right click here</span>
			<span class="hidden pointer-coarse:inline-block">Long press here</span>
		}
		@contextmenu.Content() {
			@contextmenu.Group() {
				@contextmenu.Item() {
					@icon.Copy()
					Copy
				}
				@contextmenu.Item() {
					@icon.Scissors()
					Cut
				}
				@contextmenu.Item() {
					@icon.ClipboardPaste()
					Paste
				}
			}
			@contextmenu.Separator()
			@contextmenu.Group() {
				@contextmenu.Item(contextmenu.ItemProps{Variant: contextmenu.ItemVariantDestructive}) {
					@icon.Trash()
					Delete
				}
			}
		}
	}
}
```

## Checkboxes

Use `contextmenu.CheckboxItem` for toggles.

```templ
package examples

import "github.com/axadrn/shadcn-templ/v2/components/contextmenu"

templ ContextMenuCheckboxes() {
	@contextmenu.ContextMenu() {
		@contextmenu.Trigger(contextmenu.TriggerProps{Class: "flex aspect-video w-full max-w-xs items-center justify-center rounded-xl border border-dashed text-sm"}) {
			<span class="hidden pointer-fine:inline-block">Right click here</span>
			<span class="hidden pointer-coarse:inline-block">Long press here</span>
		}
		@contextmenu.Content() {
			@contextmenu.Group() {
				@contextmenu.CheckboxItem(contextmenu.CheckboxItemProps{Checked: true}) {
					Show Bookmarks Bar
				}
				@contextmenu.CheckboxItem() {
					Show Full URLs
				}
				@contextmenu.CheckboxItem(contextmenu.CheckboxItemProps{Checked: true}) {
					Show Developer Tools
				}
			}
		}
	}
}
```

## Radio

Use `contextmenu.RadioItem` for exclusive choices.

```templ
package examples

import "github.com/axadrn/shadcn-templ/v2/components/contextmenu"

templ ContextMenuRadio() {
	@contextmenu.ContextMenu() {
		@contextmenu.Trigger(contextmenu.TriggerProps{Class: "flex aspect-video w-full max-w-xs items-center justify-center rounded-xl border border-dashed text-sm"}) {
			<span class="hidden pointer-fine:inline-block">Right click here</span>
			<span class="hidden pointer-coarse:inline-block">Long press here</span>
		}
		@contextmenu.Content() {
			@contextmenu.Group() {
				@contextmenu.Label() {
					People
				}
				@contextmenu.RadioGroup() {
					@contextmenu.RadioItem(contextmenu.RadioItemProps{Value: "pedro", Checked: true}) {
						Pedro Duarte
					}
					@contextmenu.RadioItem(contextmenu.RadioItemProps{Value: "colm"}) {
						Colm Tuite
					}
				}
			}
			@contextmenu.Separator()
			@contextmenu.Group() {
				@contextmenu.Label() {
					Theme
				}
				@contextmenu.RadioGroup() {
					@contextmenu.RadioItem(contextmenu.RadioItemProps{Value: "light", Checked: true}) {
						Light
					}
					@contextmenu.RadioItem(contextmenu.RadioItemProps{Value: "dark"}) {
						Dark
					}
					@contextmenu.RadioItem(contextmenu.RadioItemProps{Value: "system"}) {
						System
					}
				}
			}
		}
	}
}
```

## Destructive

Use `Variant: contextmenu.ItemVariantDestructive` to style the menu item as destructive.

```templ
package examples

import (
	"github.com/axadrn/shadcn-templ/v2/components/contextmenu"
	"github.com/axadrn/shadcn-templ/v2/components/icon"
)

templ ContextMenuDestructive() {
	@contextmenu.ContextMenu() {
		@contextmenu.Trigger(contextmenu.TriggerProps{Class: "flex aspect-video w-full max-w-xs items-center justify-center rounded-xl border border-dashed text-sm"}) {
			<span class="hidden pointer-fine:inline-block">Right click here</span>
			<span class="hidden pointer-coarse:inline-block">Long press here</span>
		}
		@contextmenu.Content() {
			@contextmenu.Group() {
				@contextmenu.Item() {
					@icon.Pencil()
					Edit
				}
				@contextmenu.Item() {
					@icon.Share()
					Share
				}
			}
			@contextmenu.Separator()
			@contextmenu.Group() {
				@contextmenu.Item(contextmenu.ItemProps{Variant: contextmenu.ItemVariantDestructive}) {
					@icon.Trash()
					Delete
				}
			}
		}
	}
}
```

## Sides

Control submenu placement with `Side` and `Align` props.

```templ
package examples

import "github.com/axadrn/shadcn-templ/v2/components/contextmenu"

templ ContextMenuSides() {
	<div class="grid w-full max-w-sm grid-cols-2 gap-4">
		@contextmenu.ContextMenu() {
			@contextmenu.Trigger(contextmenu.TriggerProps{Class: "flex aspect-video w-full max-w-xs items-center justify-center rounded-xl border border-dashed text-sm"}) {
				<span class="hidden pointer-fine:inline-block">Right click (top)</span>
				<span class="hidden pointer-coarse:inline-block">Long press (top)</span>
			}
			@contextmenu.Content(contextmenu.ContentProps{Side: contextmenu.SideTop}) {
				@contextmenu.Group() {
					@contextmenu.Item() {
						Back
					}
					@contextmenu.Item() {
						Forward
					}
					@contextmenu.Item() {
						Reload
					}
				}
			}
		}
		@contextmenu.ContextMenu() {
			@contextmenu.Trigger(contextmenu.TriggerProps{Class: "flex aspect-video w-full max-w-xs items-center justify-center rounded-xl border border-dashed text-sm"}) {
				<span class="hidden pointer-fine:inline-block">Right click (right)</span>
				<span class="hidden pointer-coarse:inline-block">Long press (right)</span>
			}
			@contextmenu.Content(contextmenu.ContentProps{Side: contextmenu.SideRight}) {
				@contextmenu.Group() {
					@contextmenu.Item() {
						Back
					}
					@contextmenu.Item() {
						Forward
					}
					@contextmenu.Item() {
						Reload
					}
				}
			}
		}
		@contextmenu.ContextMenu() {
			@contextmenu.Trigger(contextmenu.TriggerProps{Class: "flex aspect-video w-full max-w-xs items-center justify-center rounded-xl border border-dashed text-sm"}) {
				<span class="hidden pointer-fine:inline-block">Right click (bottom)</span>
				<span class="hidden pointer-coarse:inline-block">Long press (bottom)</span>
			}
			@contextmenu.Content(contextmenu.ContentProps{Side: contextmenu.SideBottom}) {
				@contextmenu.Group() {
					@contextmenu.Item() {
						Back
					}
					@contextmenu.Item() {
						Forward
					}
					@contextmenu.Item() {
						Reload
					}
				}
			}
		}
		@contextmenu.ContextMenu() {
			@contextmenu.Trigger(contextmenu.TriggerProps{Class: "flex aspect-video w-full max-w-xs items-center justify-center rounded-xl border border-dashed text-sm"}) {
				<span class="hidden pointer-fine:inline-block">Right click (left)</span>
				<span class="hidden pointer-coarse:inline-block">Long press (left)</span>
			}
			@contextmenu.Content(contextmenu.ContentProps{Side: contextmenu.SideLeft}) {
				@contextmenu.Group() {
					@contextmenu.Item() {
						Back
					}
					@contextmenu.Item() {
						Forward
					}
					@contextmenu.Item() {
						Reload
					}
				}
			}
		}
	</div>
}
```

## API Reference

### Content

The `contextmenu.Content` component is the menu surface, positioned at the pointer and clamped to the viewport.

| Prop          | Type                                                    | Default     |
| ------------- | ------------------------------------------------------- | ----------- |
| `Side`        | `SideTop \| SideRight \| SideBottom \| SideLeft`   | `SideRight` |
| `SideOffset`  | `int`                                                   | `0`         |
| `AlignOffset` | `int`                                                   | `4`         |
| `Class`       | `string`                                                | -           |

### Item

The `contextmenu.Item` component is a selectable entry. It renders as a link when `Href` is set and closes the menu on click.

| Prop           | Type                                          | Default          |
| -------------- | --------------------------------------------- | ---------------- |
| `Variant`      | `ItemVariantDefault \| ItemVariantDestructive` | `ItemVariantDefault` |
| `Inset`        | `bool`                                        | `false`          |
| `Disabled`     | `bool`                                        | `false`          |
| `Href`         | `string`                                      | -                |
| `Target`       | `string`                                      | -                |
| `DisableCloseOnClick` | `bool`                                        | `false`          |
| `Class`        | `string`                                      | -                |

### CheckboxItem

The `contextmenu.CheckboxItem` component is a toggleable item with a check indicator. It keeps the menu open on click.

| Prop       | Type     | Default |
| ---------- | -------- | ------- |
| `Checked`  | `bool`   | `false` |
| `Disabled` | `bool`   | `false` |
| `Class`    | `string` | -       |

### RadioGroup

The `contextmenu.RadioGroup` component wraps radio items and enforces single selection among them.

| Prop    | Type     | Default |
| ------- | -------- | ------- |
| `Class` | `string` | -       |

### RadioItem

The `contextmenu.RadioItem` component is a single-select item with a dot indicator. It keeps the menu open on click.

| Prop       | Type     | Default |
| ---------- | -------- | ------- |
| `Value`    | `string` | -       |
| `Checked`  | `bool`   | `false` |
| `Disabled` | `bool`   | `false` |
| `Class`    | `string` | -       |

### SubTrigger

The `contextmenu.SubTrigger` component opens a nested submenu on hover. Wrap it with `contextmenu.SubContent` in a `contextmenu.Sub`.

| Prop    | Type     | Default |
| ------- | -------- | ------- |
| `Inset` | `bool`   | `false` |
| `Class` | `string` | -       |
