Version 1, Update 87
APIs for dynamic page loading
Over the past few months, Figma has been rolling out dynamic page loading, which allows documents to load pages on demand, rather than all at once. For backward compatibility, Figma loads all pages in the document before attempting to run an extension (a plugin or widget), which can sometimes result in a noticeable delay.
We're pleased to announce a new set of APIs that allow extensions to work safely with dynamic page loading, and avoid triggering the loading delay. Alongside these new APIs, we are deprecating several existing methods and properties. This will help to ensure that new extensions will be compatible with dynamic page loading by default.
To mark an extension as compatible with dynamic page loading, add "documentAccess": "dynamic-page"
to manifest.json
. Extensions with this manifest field will not encounter loading delays, but they'll be unable to access any of the deprecated methods and properties listed below. New extensions will include this manifest field by default.
To learn more about updating your extension, see our comprehensive migration guide. For TypeScript users, we've also provided an ESLint plugin that can help identify and automatically fix callsites that need to be updated.
Timeline
As of February 21st, dynamic page loading APIs are generally available (GA). You can update existing extensions and create new extensions using the dynamic page loading APIs and the manifest field "documentAccess": "dynamic-page"
.
Starting in April, the manifest field "documentAccess": "dynamic-page"
will be required for all widgets, and all new plugins.
Net-new methods
Deprecations and replacements
Several methods and properties have been deprecated in favor of async
replacements:
- Use
figma.getFileThumbnailNodeAsync()
instead offigma.getFileThumbnailNode()
. - Use
figma.getLocalEffectStylesAsync()
instead offigma.getLocalEffectStyles()
. - Use
figma.getLocalGridStylesAsync()
instead offigma.getLocalGridStyles()
. - Use
figma.getLocalPaintStylesAsync()
instead offigma.getLocalPaintStyles()
. - Use
figma.getLocalTextStylesAsync()
instead offigma.getLocalTextStyles()
. - Use
figma.getNodeByIdAsync()
instead offigma.getNodeById()
. - Use
figma.getStyleByIdAsync()
instead offigma.getStyleById()
. - Use
figma.variables.getLocalVariableCollectionsAsync()
instead offigma.variables.getLocalVariableCollections()
. - Use
figma.variables.getLocalVariablesAsync()
instead offigma.variables.getLocalVariables()
. - Use
figma.variables.getVariableByIdAsync()
instead offigma.variables.getVariableById()
. - Use
figma.variables.getVariableCollectionByIdAsync()
instead offigma.variables.getVariableCollectionById()
. - Use
setRangeFillStyleIdAsync()
instead ofsetRangeFillStyleId()
. - Use
setRangeTextStyleIdAsync()
instead ofsetRangeTextStyleId()
.
In some specific cases, reading node properties has been deprecated in favor of an async
getter:
- Use
ComponentNode.getInstancesAsync()
instead ofComponentNode.instances
. - Use
getStyleConsumersAsync()
instead of theconsumers
. - Use
InstanceNode.getMainComponentAsync()
instead ofInstanceNode.mainComponent
.
In some specific cases, assigning values directly to node properties has been deprecated in favor of an async
setter:
- Use
figma.setCurrentPageAsync()
instead of assigning tofigma.currentPage
. - Use
setEffectStyleIdAsync()
instead of assigning toeffectStyleId
. - Use
setFillStyleIdAsync()
instead of assigning tobackgroundStyleId
. - Use
setFillStyleIdAsync()
instead of assigning tofillStyleId
. - Use
setGridStyleIdAsync()
instead of assigning togridStyleId
. - Use
setReactionsAsync()
instead of assigning toreactions
. - Use
setStrokeStyleIdAsync()
instead of assigning tostrokeStyleId
. - Use
setVectorNetworkAsync()
instead of assigning tovectorNetwork
. - Use
TextNode.setTextStyleIdAsync()
instead of assigning toTextNode.textStyleId
.
If an extension's manifest contains "documentAccess": "dynamic-page"
, accessing any of the deprecated items listed above will throw an exception.
Method/property usage changes
If an extension's manifest contains "documentAccess": "dynamic-page"
, calling any of the following methods will throw an exception unless you first call figma.loadAllPagesAsync():
DocumentNode.findAll()
DocumentNode.findAllWithCriteria()
DocumentNode.findOne()
DocumentNode.findWidgetNodesByWidgetId()
For the methods listed below, passing a string ID is now deprecated in favor of passing objects that the IDs refer to. If an extension's manifest contains "documentAccess": "dynamic-page"
, passing an ID will throw an exception.
figma.variables.createVariable()
- Pass aVariableCollection
object instead of a collection ID.clearExplicitVariableModeForCollection()
(present on multiple node types) - Pass aVariableCollection
object instead of a collection ID.setExplicitVariableModeForCollection()
(present on multiple node types) - Pass aVariableCollection
object instead of a collection ID.setBoundVariable()
(present on multiple node types) - Pass aVariable
object instead of a variable ID.
If an extension's manifest contains "documentAccess": "dynamic-page"
, some properties and methods of PageNode
will throw an exception unless you explicitly load the page first using PageNode.loadAsync()
. These include:
Changes to events
- If an extension's manifest contains
"documentAccess": "dynamic-page"
, thedocumentchange
event will not be available unless you first callfigma.loadAllPagesAsync()
. - Where possible, prefer using the
nodechange
andstylechange
events, which do not require triggering a full-document load.