I’m building a Figma plugin using TypeScript and the Figma API. My plugin has two main components:
main.ts file that handles Figma API calls
interface.html file containing the UI with embedded JavaScript
The plugin works with currently selected elements on the active page. I’m passing selection data from the main file to the UI like this:
let selectedElement = figma.currentPage.selection[0];
I need to monitor when users change their selection on the canvas. When figma.currentPage.selection updates, I want to automatically send the new selection data to my UI.
What’s the best approach to listen for selection changes in Figma plugins? Any suggestions would be helpful.
u can use the selectionchange event! like, add figma.on('selectionchange', () => { /* ur code */ }) in main.ts. it’ll trigger when the selection changes. after that, just send the new selection data to ur ui with figma.ui.postMessage().
The selectionchange event is definitely the right approach, but there are some implementation details worth mentioning. When you set up the event listener, make sure to handle cases where the selection might be empty or contain multiple elements. I usually wrap the selection data in a try-catch block before sending it to the UI because sometimes the selection can change rapidly and cause timing issues. Also, consider debouncing the event if your plugin does heavy processing, since users might drag across multiple elements quickly. The event fires immediately when selection changes, so you get real-time updates without polling. Just remember that the event only fires in the main thread, so all your selection processing logic needs to be in main.ts before you send the processed data to your interface.
Building on what others mentioned about the selectionchange event, I ran into performance issues when I first implemented this in my own plugin. The event can fire extremely frequently during certain user interactions, especially when selecting groups or components with many nested elements. What helped me was caching the previous selection state and comparing it before processing. I store a simple hash or ID of the current selection and only trigger my UI updates when it actually differs from the cached version. This prevents unnecessary postMessage calls to the interface. Another thing to watch out for is that the selection array can contain nodes that might get deleted or moved between pages while your event handler is processing them. I learned to validate that selectedElement.removed is false before accessing any properties. Also worth noting that the event doesn’t distinguish between programmatic selection changes versus user-initiated ones, so if your plugin modifies selection programmatically, you might need to add flags to prevent infinite loops.