Custom Context Menu for Openlayers
npm install ol-contextmenu> A customizable, feature-rich context menu extension for OpenLayers maps

Quick Links: Demo ⢠Installation ⢠Quick Start ⢠API ⢠TypeScript ⢠Examples
---
- šÆ Easy Integration - Works seamlessly with OpenLayers 7.x - 10.x
- šØ Fully Customizable - Control width, icons, styles, and appearance
- š Nested Submenus - Unlimited nesting levels for complex menu structures
- š¦ Zero CSS Dependencies - Styles are bundled inline (since v6.0)
- šŖ Event-Driven - React to beforeopen, open, and close events
- š Multiple Trigger Types - Context menu, click, or double-click
- š± Viewport-Aware - Automatically repositions to stay visible at screen edges
- šŖ TypeScript Support - Full type definitions included out of the box
- ā” Lightweight - Minimal footprint with only one dependency (tiny-emitter)
- ā
Well Tested - 191 tests covering all functionality
Try it live:
- š® CodeSandbox - Interactive demo with full source
- š JSFiddle - Quick playground
- š» Local Examples - Webpack, Vite, and CDN examples
npm (Recommended):
``bash`
npm install ol ol-contextmenu
CDN:
`html`
Requires: OpenLayers 7.0.0 or higher
š See Getting Started Guide for detailed installation instructions and setup.
`javascript
import ContextMenu from 'ol-contextmenu';
const contextmenu = new ContextMenu({
width: 170,
defaultItems: true, // Includes Zoom In/Zoom Out
items: [
{
text: 'Center map here',
callback: (obj, map) => {
map.getView().setCenter(obj.coordinate);
},
},
{
text: 'Add a Marker',
icon: 'img/marker.png',
callback: addMarker,
},
'-', // Separator
],
});
map.addControl(contextmenu);
`
š See Getting Started Guide for complete setup instructions and Examples for advanced patterns.
- Getting Started - Installation and basic setup
- API Reference - Complete API documentation
- TypeScript Guide - TypeScript usage and type definitions
- Examples & Recipes - Common patterns and code examples
- Troubleshooting - Common issues and solutions
Full TypeScript support with comprehensive type definitions included:
`typescript
import ContextMenu, { type Item } from 'ol-contextmenu';
const items: Item[] = [
{
text: 'Center map here',
callback: (obj, map) => {
map.getView().setCenter(obj.coordinate);
},
},
];
const contextmenu = new ContextMenu({ width: 170, items });
`
š See the TypeScript Guide for complete type definitions and usage patterns.
`javascript`
new ContextMenu(options)
Options:
- width (number, default: 150) - Menu width in pixelsdefaultItems
- (boolean, default: true) - Include default Zoom In/Out itemsitems
- (Item[], default: []) - Array of menu itemseventType
- (string, default: 'contextmenu') - Event type to trigger menu
- clear() - Remove all itemsclose()
- - Close menu programmaticallyextend(items)
- - Add multiple itemspush(item)
- - Add single itempop()
- / shift() - Remove itemsgetDefaultItems()
- - Get default items arrayisOpen()
- - Check if menu is openenable()
- / disable() - Control menu state
- beforeopen - Fired before menu opensopen
- - Fired when menu opensclose
- - Fired when menu closes
š See API Reference for complete documentation with examples.
- Examples & Recipes - Common patterns and code examples
- Local Examples - Complete working projects:
- CDN Example - No build tools required
- Webpack Example - Integration with Webpack
- Vite Example - Modern setup with Vite + TypeScript
Common issues:
- Menu doesn't appear: Ensure map.addControl(contextmenu) is calledimport ContextMenu, { type Item } from 'ol-contextmenu'
- Menu cut off: Update to v5.5.0+ for automatic viewport positioning
- TypeScript errors: Use
š See the Troubleshooting Guide for detailed solutions and common issues.
Modern browsers supporting ES6+:
- Chrome/Edge (latest)
- Firefox (latest)
- Safari (latest)
Contributions are welcome! We appreciate:
- š Bug reports
- š” Feature requests
- š Documentation improvements
- ⨠Code contributions
Please read our Contributing Guidelines before submitting a PR.
`bashClone the repository
git clone https://github.com/jonataswalker/ol-contextmenu.git
cd ol-contextmenu
MIT Ā© Jonatas Walker
Built with ā¤ļø for the OpenLayers community.
Special thanks to all contributors who have helped improve this project.
---
Made with ā¤ļø by the community