Common issues and solutions for ol-contextmenu.
Symptoms:
Error: Cannot find module 'ol-contextmenu'
Solutions:
-
Verify installation:
npm list ol-contextmenu
-
Reinstall the package:
npm install ol-contextmenu
-
Clear cache and reinstall:
rm -rf node_modules package-lock.json npm install
Symptoms:
Could not find a declaration file for module 'ol-contextmenu'
Solutions:
Type definitions are included since v6.0. Make sure you're on the latest version:
npm install ol-contextmenu@latestIf the issue persists, check your tsconfig.json:
{
"compilerOptions": {
"moduleResolution": "node",
"esModuleInterop": true
}
}Symptoms:
- Right-clicking does nothing
- No context menu visible
Solutions:
-
Verify the control is added to the map:
map.addControl(contextmenu);
-
Check if menu is disabled:
contextmenu.enable(); // Re-enable if needed
-
Verify event type:
const contextmenu = new ContextMenu({ eventType: 'contextmenu', // Default });
-
Check browser console for errors
-
Ensure OpenLayers version compatibility:
npm list ol # Should be 7.0.0 or higher
Symptoms:
- Menu is partially hidden at screen edges
- Bottom or right side of menu is cut off
Solution:
Update to v5.5.0 or higher (automatic viewport positioning):
npm install ol-contextmenu@latestThe menu now automatically repositions to stay within viewport bounds.
Symptoms:
- Menu appears unstyled
- CSS classes not applied
Solutions:
-
Verify you're on v6.0+ (CSS is bundled):
npm list ol-contextmenu
-
Remove old CSS imports:
- import 'ol-contextmenu/dist/ol-contextmenu.css'; // Remove this -
Clear build cache:
rm -rf dist/ npm run build
-
Check for CSS conflicts in browser DevTools
Symptoms:
- Menu items don't respond to clicks
- Callback functions never execute
Solutions:
-
Verify callback syntax:
// ✅ Correct { text: 'Test', callback: (obj, map) => { console.log('Clicked!'); } } // ❌ Wrong - missing parameters { text: 'Test', callback: () => { console.log('Clicked!'); } }
-
Check for JavaScript errors in console
-
Ensure item has callback:
// Separators don't have callbacks '-' // This is correct // Items need callbacks { text: 'Test', callback: fn } // Needs callback
Symptoms:
- Menu opens and closes instantly
- Can't click menu items
Solutions:
-
Check for conflicting click handlers:
// Avoid stopPropagation on map clicks map.on('click', (evt) => { // Don't stopPropagation here });
-
Verify beforeopen handler:
contextmenu.on('beforeopen', (evt) => { // Don't call closeMenu() here // Don't disable() immediately });
Symptoms:
- Menu items don't change based on context
- Same items always show
Solutions:
-
Clear menu before updating:
contextmenu.on('beforeopen', (evt) => { contextmenu.clear(); // Important! contextmenu.extend(newItems); });
-
Use correct event:
// ✅ Use beforeopen for menu changes contextmenu.on('beforeopen', updateMenu); // ❌ Don't use open (too late) // contextmenu.on('open', updateMenu);
Symptoms:
Module '"ol-contextmenu"' has no exported member 'ContextMenu'Solution:
Use correct import syntax:
// ✅ Correct - default import
import ContextMenu from 'ol-contextmenu';
// ❌ Wrong - named import
// import { ContextMenu } from 'ol-contextmenu';Symptoms:
Type '{ text: string; }' is missing the following properties: callbackSolution:
Provide type annotations:
import { type Item, type SingleItem } from 'ol-contextmenu';
// Option 1: Type the array
const items: Item[] = [
{ text: 'Test', callback: (obj, map) => {} }
];
// Option 2: Type individual items
const item: SingleItem = {
text: 'Test',
callback: (obj, map) => {}
};Symptoms:
- Delay before menu appears
- Laggy interaction
Solutions:
-
Optimize beforeopen handler:
// ❌ Slow - recalculating every time contextmenu.on('beforeopen', (evt) => { const items = expensiveCalculation(); contextmenu.extend(items); }); // ✅ Fast - calculate once const items = expensiveCalculation(); contextmenu.on('beforeopen', (evt) => { contextmenu.extend(items); });
-
Reduce number of items (use submenus for large lists)
-
Avoid DOM operations in callbacks:
// ❌ Slow callback: () => { document.querySelectorAll('.heavy-selector').forEach(/* ... */); } // ✅ Fast callback: () => { cachedElements.forEach(/* ... */); }
Symptoms:
- Works in Chrome/Firefox but not Safari
Solutions:
- Check Safari version (modern versions only)
- Verify ES6 support (Safari 10+)
- Check for polyfills needed
Symptoms:
- Both custom and browser context menus show
Solution:
This is expected behavior. The library prevents default for contextmenu events, but some browsers may still show their menu. This is handled correctly by the library.
Symptoms:
Module parse failed: Unexpected token
Solution:
Update Webpack config to handle ES modules:
module.exports = {
module: {
rules: [
{
test: /\.js$/,
include: /node_modules\/ol-contextmenu/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env']
}
}
}
]
}
};Solution:
Vite should work out of the box. If you encounter issues:
// vite.config.js
export default {
optimizeDeps: {
include: ['ol-contextmenu']
}
};If your issue isn't covered here:
-
Search existing issues: GitHub Issues
-
Check the examples: Examples Directory
-
Review the API documentation: API Reference
-
Create a new issue:
When creating an issue, please include:
- ol-contextmenu version
- OpenLayers version
- Browser and version
- Minimal reproduction example
- Error messages
- What you've tried