Skip to main content

How Widgets Run

Widgets run inside the same sandbox as Plugins but with the additional ability to:

  • Create a custom object that lives on the canvas
  • Respond to user interactions on these custom objects

Widgets only run in response to user interaction and only on the specific client that initiated this interaction. All other clients will see the updated widget via regular updates to the file, via Multiplayer.

As pictured above, it is helpful to think about Widget Code in 2 distinct parts:

  1. Rendering Code that describes how a widget should look
  2. State Updating Code that updates widget state

Rendering Code

Code that describes how a widget should look runs synchronously and should solely depend on a widget’s state in order to avoid inconsistencies when rendering across multiple clients. For instance, a widget shouldn’t depend on attributes of other nodes on the canvas when deciding how it looks.

If you want to use something like figma.activeUsers in your widget, the recommended pattern is to use a lazy default initializer to initialize a synced state value.

This will be enforced at the API level - widget rendering code won’t be able to read and access data outside of the particular widget’s state.

State Updating Code

Code that updates widget state runs asynchronously and can do much more than read the widget state. It will have full read/write access to the document via the Plugin API. Code here can also make network requests via iframes and open iframes to get more user input. Most commonly, code here ends up updating the widget state, which will cause the widget to re-render.

Network access

Additional network security is enforced if your widget limits network access. When network access is limited, if your widget attempts to access a domain that isn't specified in your widget's manifest, Figma blocks that attempt and returns a content-security policy (CSP) error.

The enforcement of domain access is limited only to requests made by the widget, such as Fetch API requests to a public REST API. If your widget renders a website in an iframe, network access limits only apply directly to the website's domain.Network access limits do not affect resources needed by that website. For example, suppose your widget frames and limits access only to Your widget would be prevented from rendering content from other domains. However, would still be able to load external resources, such as scripts for Google Analytics.