Inconsistent plugin behavior in figma app and browser

I use drop event to receive data from plugin and create component in figma, it works fine in figma app but not in browser.

figma.on('drop', event => {
  const { items, node } = event
  if (items.length > 0 && items[0].type === 'text/json') {
    const data = JSON.parse(items[0].data) as IconData
    const instance = newIconFromData(data)
    instance.x = event.x
    instance.y = event.y
    // not all nodes have appendChild method
    ;(node as PageNode | FrameNode | GroupNode | SectionNode).appendChild(instance)
    figma.currentPage.selection = [instance]
    return false
  return true

I also tested on Material-Symbols and it doesn’t drop properly in browser too.
My os version is macos 13.2 and browser verison is chrome 110, and there’s no error message in console after I drop.
Any idea on how to solve this? Thanks.

Hi! Figma engineer here. Thanks for flagging. Unfortunately, I wasn’t able to reproduce the issue. Would you be able to provide the plugin code, including the UI file? It’d be also helpful if you have a video of the issue.

  • I tested the Material Symbols plugin. That plugin doesn’t use a drop handler, so the drop event doesn’t work on desktop or browser.
  • I tested that the following plugin code works on desktop and browser. For more examples, you can see the png crop or icon drag and drop plugins.


<span id="icon" draggable="true">
    viewBox="0 0 24 24"
    class="feather feather-align-center"
    <line x1="18" y1="10" x2="6" y2="10"></line>
    <line x1="21" y1="6" x2="3" y2="6"></line>
    <line x1="21" y1="14" x2="3" y2="14"></line>
    <line x1="18" y1="18" x2="6" y2="18"></line>
  const icon = document.getElementById("icon");
  icon.addEventListener("dragend", (e) => {
    // Don't proceed if the item was dropped inside the plugin window.
    if (e.view.length === 0) return;

    const item = {
      type: "text/json",
      data: '{ "width": 100, "height": 200 }',
    // This will trigger a drop event in Figma that we can register a callback for
        pluginDrop: {
          clientX: e.clientX,
          clientY: e.clientY,
          items: [item],



type Data = {
  width: number,
  height: number,

figma.on('drop', event => {
  const { items, node } = event;
  if (items.length > 0 && items[0].type === 'text/json') {
    const data = JSON.parse(items[0].data) as Data;

    const rect = figma.createRectangle();
    rect.x = event.absoluteX;
    rect.y = event.absoluteY;
    rect.resize(data.width, data.height);

    // not all nodes have appendChild method
    (node as PageNode | FrameNode | GroupNode | SectionNode).appendChild(rect)
    figma.currentPage.selection = [rect]
    return false
  return true

Thanks for responding!
I use a script tag to redirect ui.html to a webpage serving in my local network like this:

const ui = `<script>window.location.href = ""</script>`

and the drag event I use is dragstart like plugin api document

const handleDragStart = (e: DragEvent) => {
  if (!iconConfig.value) {
  const options = getOptions()
  const data = preparePluginIconData(props.icon.display_name, iconConfig.value, options)
  e.dataTransfer!.setData('text/json', JSON.stringify(data))

I can’t test a unpublished plugin in browser, would that makes the difference?

here’s my screen recording of the issue.

Hi @Elaine_Lin, we are also running into this issue!
It seems to impact Non-null origin iframes in particular.

Some additional context & reports for things that sound similar/related across the community forum (all of which have gone unanswered):

We would love to get this resolved / any suggestions for workarounds!

Also want to echo that it is very difficult for plugin authors to catch issues like this before a plugin is released, because you cannot test a plugin in the browser before it is released! So any discrepancies between the Figma desktop app and the Figma browser experience go undetected through the review process :frowning: . Any possibility of being able to test dev plugins in the browser in the future?

Lastly, is there a way via the plugin API or otherwise to detect whether a plugin is being executed in the browser or desktop app? Then we can at least ship a quick patch release to notify users about the missing drag-and-drop behavior on the web.