Version 1, Update 96
Updates
Fix plugin typings bug for prototype expressions. The ExpressionFunction enum has been updated to include a previously missing value: NOT.
Fix plugin typings bug for prototype expressions. The ExpressionFunction enum has been updated to include a previously missing value: NOT.
Fix plugin typings bug for typography variables. Instances of keyof Omit<VariableBindableTextField, '...'> have been updated to Exclude<VariableBindableTextField, '...'>, which correctly excludes values from the VariableBindableTextField enum.
VariableScopes now have support for typography variables:
STRING variable scopes: FONT_FAMILY, FONT_STYLE, TEXT_CONTENTFLOAT variable scopes: FONT_SIZE, LINE_HEIGHT, LETTER_SPACING, PARAGRAPH_SPACING, PARAGRAPH_INDENTboundVariables that contains a color field and denotes whether a variable is bound to a gradient color stop.figma.constants.colors does not exist. This object, which remains exactly the same in the API, defines color palettes. We currently support the official FigJam colors, which can be found on this Figma Learn page.
ColorPalettes to hold all the available ColorPalette objectsWith the launch of typography variables, the plugin API now supports getting and setting bound variables for text properties like font family, font style, font weight, and more. Please refer to the Working with Variables guide for how to use the variables API to control typography in Figma files.
New:
node.getRangeBoundVariable and node.setRangeBoundVariable for getting and setting bound variables on text ranges.Updated:
node.boundVariables now includes bindable text fields.node.setBoundVariable can bind variables to text fields for the full text range in a text node.TextStyle.node.getStyledTextSegments now include bound variables for text fields to let you easily identify bindings across segments of text in a text node.fontStyle.openTypeFeatures entry to the list of properties that may be reported in documentchange or nodechange events. See NodeChangeProperty.networkAccess in the plugin and widget docs.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.
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.
Several methods and properties have been deprecated in favor of async replacements:
figma.getFileThumbnailNodeAsync() instead of figma.getFileThumbnailNode().figma.getLocalEffectStylesAsync() instead of figma.getLocalEffectStyles().figma.getLocalGridStylesAsync() instead of figma.getLocalGridStyles().figma.getLocalPaintStylesAsync() instead of figma.getLocalPaintStyles().figma.getLocalTextStylesAsync() instead of figma.getLocalTextStyles().figma.getNodeByIdAsync() instead of figma.getNodeById().figma.getStyleByIdAsync() instead of figma.getStyleById().figma.variables.getLocalVariableCollectionsAsync() instead of figma.variables.getLocalVariableCollections().figma.variables.getLocalVariablesAsync() instead of figma.variables.getLocalVariables().figma.variables.getVariableByIdAsync() instead of figma.variables.getVariableById().figma.variables.getVariableCollectionByIdAsync() instead of figma.variables.getVariableCollectionById().setRangeFillStyleIdAsync() instead of setRangeFillStyleId().setRangeTextStyleIdAsync() instead of setRangeTextStyleId().In some specific cases, reading node properties has been deprecated in favor of an async getter:
ComponentNode.getInstancesAsync() instead of ComponentNode.instances.getStyleConsumersAsync() instead of the consumers.InstanceNode.getMainComponentAsync() instead of InstanceNode.mainComponent.In some specific cases, assigning values directly to node properties has been deprecated in favor of an async setter:
figma.setCurrentPageAsync() instead of assigning to figma.currentPage.setEffectStyleIdAsync() instead of assigning to effectStyleId.setFillStyleIdAsync() instead of assigning to backgroundStyleId.setFillStyleIdAsync() instead of assigning to fillStyleId.setGridStyleIdAsync() instead of assigning to gridStyleId.setReactionsAsync() instead of assigning to reactions.setStrokeStyleIdAsync() instead of assigning to strokeStyleId.setVectorNetworkAsync() instead of assigning to vectorNetwork.TextNode.setTextStyleIdAsync() instead of assigning to TextNode.textStyleId.If an extension's manifest contains "documentAccess": "dynamic-page", accessing any of the deprecated items listed above will throw an exception.
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 a VariableCollection object instead of a collection ID.clearExplicitVariableModeForCollection() (present on multiple node types) - Pass a VariableCollection object instead of a collection ID.setExplicitVariableModeForCollection() (present on multiple node types) - Pass a VariableCollection object instead of a collection ID.setBoundVariable() (present on multiple node types) - Pass a Variable 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:
"documentAccess": "dynamic-page", the documentchange event will not be available unless you first call figma.loadAllPagesAsync().nodechange and stylechange events, which do not require triggering a full-document load.