Widget Manifest
Each widget must define a manifest.json
file. If you use the "Create new widget" option, Figma will automatically create a simple manifest for you.
Here’s an example of a widget manifest file:
This file is similar to the plugin manifest with the additional containsWidget
and widgetApi
properties and without plugin-specific options like menus or relaunchButtons.
{
"name": "MyWidget",
"id": "737805260747778093",
"api": "1.0.0",
"widgetApi": "1.0.0",
"editorType": ["figma", "figjam"],
"containsWidget": true,
"main": "code.js",
"ui": "ui.html",
"documentAccess": "dynamic-page",
"networkAccess": {
"allowedDomains": ["none"]
}
}
name: string
The name of the widget, as it will appear in the menu.
id?: string
The widget ID to publish updates to. This ID will be assigned to you by Figma and is typically obtained using the "Create new Widget" feature, which will generate a manifest file with a new id
. You can also get a new widget ID at the time of publishing your widget.
widgetApi: string
The version of the widget API used by the widget. The current widgetApi version is "1.0.0"
. In the future, when there are more versions of the widget API, this will be used to ensure stability across widget versions. See Stability and Updates for more information about updates to the api.
We recommend updating to the latest version whenever possible to get the latest features, bug fixes, and documentation.
containsWidget: true
All widget manifests should have this set to true.
editorType: ('figma' | 'figjam')[]
This allows you to specify the editor that your widget is intended for and will impact which editor your widget appears in.
The types we support currently are:
"editorType": ["figma"]
"editorType": ["figjam"]
"editorType": ["figma", "figjam"]
main: string
The relative file path to the JavaScript code of your widget.
ui?: string | { [key: string]: string }
Used to specify HTML file/files that can be used in the iframe modal via figma.showUI
, if you choose to have one.
- If a single string is specified, this is the relative file path to the HTML file whose contents will be available as a string in the Javascript code via the constant
__html__
. - If a map is specified, each entry of the map will be available at
__uiFiles__
documentAccess?: 'dynamic-page'
This field ensures the widget supports dynamic page loading. The field is required for all new widgets and the value must be dynamic-page
.
- If the manifest field is included, then the widget will run immediatley.
- If the manifest field is not included, then when the widget is run or interacted with for the first time after a user opens a file, the entire file will load and Figma will show a "Loading n pages for widget…" notification, where
n
is the number of pages being loaded.
If your existing widget's manifest doesn't include this field, you should migrate your widget to use dynamic page loading.
This field is required for all new widgets and new versions of widgets.
networkAccess?: NetworkAccess
This property is currently in public beta and is subject to change.
Used to specify the list of domains that your widget is permitted to access. When networkAccess
is used:
-
Your widget can only access the domains that you specify. If your widget attempts to access other domains, the widget is prevented from doing so.
noteThe enforcement of network access is limited only to requests made by the widget, such as requests to a public API. In a situation such as a widget rendering a website in a frame, network access limits only apply to the website's domain. Network access limits don’t affect the website’s resources.
-
The list of domains that your widget can access is displayed on your widget's Community page.
networkAccess
has the following properties:
allowedDomains
is a required list of strings. The strings are match patterns for domains that your widget is permitted to access. IfnetworkAccess
is used,allowedDomains
must include at least one pattern. Optionally, patterns can start with one of the permitted schemes:http
,https
,ws
, orwss
. The*
character may be used as a wildcard for subdomains, or used to represent all domains.reasoning
is a usually-optional string that describes why your widget needs to access the allowed domains.reasoning
is required if:- Your
allowedDomains
list includes"*"
- Your
allowedDomains
list includes local or development servers. If you only need local or development servers for development, please usedevAllowedDomains
instead.
- Your
devAllowedDomains
is an optional list of strings. The strings are match patterns for domains that your widget is permitted to access during development. You can use most of the same patterns indevAllowedDomains
as you can inallowedDomains
.
Valid patterns for allowedDomains
:
["none"]
: The widget cannot access any external network resources. Note that we preload the Inter font for use in widgets, so you don't need to include an Inter font source in your allowedDomains.
Valid patterns for allowedDomains
and devAllowedDomains
:
["*"]
: The widget may access any external network resources. If this pattern is included inallowedDomains
, thereasoning
property is required.["*.example.com"]
: The*
character can be used to permit all subdomains of a given domain.["http://example.com", "https://example.com", "ws://example.com", "wss://example.com"]
:http
,https
,ws
, andwss
are permitted schemes that can be used to prefix domains. Other schemes, such asfile
, cannot be used.["api.example.com/rest/get", "www.example.com/images/", "http://s3.amazonaws.com/example_bucket/"]
: URLs to specific resources can be used.["example.com", "figma.com"]
: Domains can be used without schemes, subdomains, or wildcards.["http://localhost", "https://localhost", "http://localhost:3000", "http://localhost:8081"]
: During development, the widget can access a local/development web server. If the server is running on a port other than port 80, the port number can be provided after the URL. If this pattern is included inallowedDomains
, thereasoning
property is required.
In the previous example, the trailing slash in www.example.com/images/
identifies a path to multiple resources. For example, www.example.com/images/
lets a widget access images at www.example.com/images/img1.png
and www.example.com/images/img2.png
.
A pattern with no trailing slash blocks any deeper access to files on that path. For example, api.example.com/rest/get
stops a widget from accessing api.example.com/rest/get/exampleresource.json
. This can be useful, for example, if your widget uses a REST API endpoint and you want to restrict the widget to that endpoint only.
For example:
"networkAccess": {
"allowedDomains": [
"figma.com",
"*.google.com",
"https://my-app.cdn.com",
"wss://socket.io",
"example.com/api/",
"exact-path.com/content"
],
"devAllowedDomains": [
"http://localhost:3000"
]
}
More formally,
interface NetworkAccess {
allowedDomains: string[]
reasoning?: string
devAllowedDomains: string[]
}
build?: string
Experimental! A shell command to run before we load the file specified in main
and ui
. This can be used to call build commands such as compiling with Typescript, running Webpack, etc. The command is run in the directory of the manifest.
Plugin API Specific Options
Here are some plugin specific manifest options that are also applicable to widgets:
api: string
The version of the Figma Plugin API used by the widget. We recommend updating to the latest version whenever possible to get the latest features, bug fixes, and documentation.
permissions?: PermissionType[]
This allows you to specify what permissions your widget wants access to.
type PermissionType =
"currentuser" |
"activeusers"
activeuser
must be specified if your widget uses figma.activeUser
and currentuser
must be specified if your widget uses figma.currentUser
.
enableProposedApi?: boolean
See Plugin Proposed API.
This flag is only meant for development, and will not work in published widgets!
enablePrivatePluginApi?: boolean
This enables Plugin API that's specific to private widgets. Setting this will also enable local widgets to work with these APIs during development.