Edit in GitHubLog an issue

UXP Manifest v5

Manifest v5 gives developers access to a new plugin permissions model and WebViews in modal dialogs. Using the full manifest v5 feature set requires PS 23.3.0 or higher. (UXP 6.0 or higher)

Upgrade your plugin to use the latest manifest feature set by changing the manifestVersion element.

Copied to your clipboard
"manifestVersion": 5

Example manifest#

Copied to your clipboard
1{
2 "manifestVersion": 5,
3 "id": "YOUR_ID_HERE",
4 "name": "Name of your plugin",
5 "version": "1.0.0",
6 "main": "index.html",
7 "host": {
8 "app": "PS",
9 "minVersion": "23.3.0"
10 },
11 "entrypoints": [
12 {
13 "type": "command",
14 "id": "commandFn",
15 "label": {
16 "default": "Show A Dialog"
17 }
18 },
19 {
20 "type": "panel",
21 "id": "panelName",
22 "label": {
23 "default": "Panel Name"
24 },
25 "minimumSize": {"width": 230, "height": 200},
26 "maximumSize": {"width": 2000, "height": 2000},
27 "preferredDockedSize": {"width": 230, "height": 300},
28 "preferredFloatingSize": {"width": 230, "height": 300},
29 "icons": [
30 {"width":23,"height":23,"path":"icons/dark.png","scale":[1,2],"theme":["darkest","dark","medium"]},
31 {"width":23,"height":23,"path":"icons/light.png","scale":[1,2],"theme":["lightest","light"]}
32 ]
33 }
34 ],
35 "icons": [
36 { "width": 23, "height": 23, "path": "icons/icon_D.png", "scale": [ 1, 2 ], "theme": [ "dark", "darkest" ], "species": [ "generic" ] },
37 { "width": 23, "height": 23, "path": "icons/icon_N.png", "scale": [ 1, 2 ], "theme": [ "lightest", "light" ], "species": [ "generic" ] }
38 ],
39 "requiredPermissions": {
40 "network": {
41 "domains": [
42 "https://adobe.com",
43 ]
44 },
45 "clipboard": "readAndWrite",
46 "webview": {
47 "allow": "yes",
48 "domains": [ "https://*.adobe.com", "https://*.google.com"]
49 },
50 "launchProcess": { 
51 "schemes":
52 [ "https", "slack"],        
53 "extensions":
54 [ ".xd", ".psd" ]   
55 }, 
56 },
57}

Changes to top-level metadata#

Starting from changes to top-level metadata, here are some keys that changed with the v5 upgrade. Read manifest v4 to learn more about each key/value field.

Key pathTypeDescriptionChange
versionstringVersion number of your plugin in x.y.z format.Plugins can specify semver format with no warnings.
Specify at least one number and the minor and/or patch will be autofilled with zeroes.
requiredPermissionsobjectDeclare plugin permissions.New in v5.
entrypointsEntryPointDefinition[]Describes the entries your plugin adds to the Plugins menu and plugin panel.v5 changes in next section.

Updates to Entrypoints methods#

With manifest v4:

  • Promise-based methods were not supported for entrypoint methods.
  • No timeouts for entrypoints methods.
  • All panel entrypoints have only one argument event which contains node, panel, eventName and PanelID.

Manifest v5 brings additional lifecycle events to better manage your plugin and more flexibility in specifying the initial view and location of plugins' panels:

  • UXP honors promises returned by (most) entrypoint methods.
    • Plugin entrypoints: Promise support is enabled for plugin destroy.
    • Panel entrypoints: Promise support is enabled for panel create, show, destroy, hide.
    • Currently, panel show is tied to plugin create, and panel hide is tied to plugin destroy.
  • Entrypoint methods have a timeout of 300 milliseconds
  • Panel entrypoints have rootNode as first argument and data as second argument for show and hide.

entrypoints.setup() using promises#

Copied to your clipboard
1import { entrypoints } from "uxp";
2entrypoints.setup({
3 plugin: {
4 create() {
5 console.log("Plugin has been loaded, plugin.create has been triggered.");
6 },
7 destroy() {
8 return new Promise(function (resolve, reject) {
9 console.log("Plugin has been loaded, plugin.create has been triggered.");
10 resolve();
11 });
12 }
13 },
14 panels: {
15 panelA: {
16 create(rootNode) {
17 return new Promise(function (resolve, reject) {
18 console.log("PanelA is created, panelA.create has been triggered.");
19 resolve();
20 });
21 },
22 show(rootNode, data) {
23 return new Promise(function (resolve, reject) {
24 console.log("PanelA is about to be displayed, panelA.show has been triggered with data ", data);
25 resolve();
26 });
27 },
28 hide(rootNode, data) {
29 return new Promise(function (resolve, reject) {
30 console.log("PanelA is about to be hidden, panelA.hide has been triggered with data ", data);
31 resolve();
32 });
33 },
34 destroy(rootNode) {
35 return new Promise(function (resolve, reject) {
36 console.log("PanelA is about to be destroyed, panelA.destroy has been triggered.");
37 resolve();
38 });
39 },
40 invokeMenu(menuId) {
41 return new Promise(function (resolve, reject) {
42 console.log("A menu item on PanelA has been invoked, panelA.invokeMenu has been triggered with menu id ", menuId);
43 resolve();
44 });
45 },
46 menuItems: [...]
47 },
48 "panelB": {..}
49 },
50 commands: {
51 "command1": {
52 run() {..},
53 cancel() {..}
54 },
55 "command2": function(){..}
56 }
57});

Plugin Permissions#

Plugins using Manifest v5 will enjoy the enhancements in security with the introduction of new permissions model. Users will be asked for their consent when your plugin attempts to use openExternal, openPath, and sp-link/anchor tags. For everything else, consent is given at install time.

Starting with v5, any permissions not explicitly declared in the manifest are not granted by default.

Network#

In order for our plugin to use the network, you must define domains that your plugin will access. You can do this by adding the network object to the requiredPermissions section of the manifest.

Copied to your clipboard
1{
2 "requiredPermissions": {
3 "network": {
4 "domains": [
5 "https://source.unsplash.com",
6 ]
7 }
8 }
9}
Copied to your clipboard
<img src='https://source.unsplash.com/random'>

Clipboard#

To grant read and/or write access to the system clipboard, declare it in requiredPermissions. clipboard accepts:

  • readAndWrite for read/write access
  • read for read-only access.
Copied to your clipboard
1{
2 "requiredPermissions": {
3 "clipboard": "readAndWrite"
4 }
5}
Copied to your clipboard
1const clipboard = navigator.clipboard;
2const dataTransferProviders = {
3 'text/plain': 'Sample text'
4};
5clipboard.writeText(dataTransferProviders).then(
6 (result) => {...},
7 (error) => {...}
8);

Local Filesystem#

The localFileSystem permission controls access to the user's local file system. If not specified, the plugin has no access to the user's file system other than the default access to plugin://, plugin-temp://, and plugin-data://.

localFileSystem accepts:

  • request: Allows the plugin to access the local file system using pickers for opening and saving files.
  • plugin: Allows the plugin to access the plugin's storage only.
  • fullAccess: Allows the plugin to inspect, modify, and delete files to which you have access on all volumes attached to this device. The user will be required to consent before installation or update.
Copied to your clipboard
1{
2 "requiredPermissions": {
3 "localFileSystem": "request"
4 }
5}
Copied to your clipboard
1const fs = require('uxp').storage.localFileSystem;
2const file = await fs.getFileForSaving('manifest_demo.txt');
3await file.write('Manifest v5 demo');

If plugin is not specified for plugin storage, the manifest will default to that setting.

Launch Process#

The launchProcess permission in the manifest controls the ability to launch applications and open files in other applications.

With manifest v5, the launchProcess permission must be declared to use openExternal or openPath.

Copied to your clipboard
1"permissions": {        
2 "launchProcess": {   
3 // allows launching files with specified URI schemes         
4 "schemes": 
5 [ "https", "slack", "adbxd" ],   
6 // allows opening files with the specified file extensions          
7 "extensions": 
8 [ ".pdf", ".xd", ".psd" ],       
9 },   
10}

Both openPath and openExternal rely on this permission set, and upon either function call, the user will get a runtime consent dialog. Only after they agree will the API call execute.

Plugin communication#

If enabled, the plugin can communicate with other installed plugins. Defaults to false.

Copied to your clipboard
1"permissions": {        
2 "ipc": {
3 "enablePluginCommunication": true   
4 }
5}
Copied to your clipboard
1const { pluginManager } = require("uxp");
2// find the Alchemist plugin in the loaded plugins
3const alchemistPlugin = Array.from(pluginManager.plugins).find(plugin => plugin.id==="2bcdb900");
4//What commands and panels are available?
5const alchemistCommands = Array.from(alchemistPlugin.manifest.commands, command => command.commandId); // result: ["resetStateFn"]
6const alchemistPanels = Array.from(alchemistPlugin.manifest.panels, command => command.panelId); // result: ["inspector"]
7// Show the inspector panel; note that panels can only be made visible -- you can't ask to hide the panel
8alchemistPlugin.showPanel("inspector");
9// Reset Alchemists state... but be sure you want to do this!
10alchemistPlugin.invokeCommand("resetStateFn");

WebViews#

WebViews are available with UXP 6.0, and need to be configured in your plugin's manifest (v5 required).

In your manifest.json:

Copied to your clipboard
1{
2 "manifestVersion": 5,
3 "requiredPermissions": {
4 "webview": {
5 "allow": "yes",
6 // domains --> string[] | "all"
7 "domains": [ "https://*.adobe.com", "https://*.google.com"],
8 }
9 }
10}

Then in your plugin's code:

Copied to your clipboard
1<dialog>
2 <webview id="webview" width="100%" height="360px" src="https://www.adobe.com"></webview>
3</dialog>
Copied to your clipboard
document.querySelector("dialog").showModal();

Webview

Limitations#

WebViews are available within modal dialogs only for now.

Was this helpful?
  • Privacy
  • Terms of Use
  • Do not sell my personal information
  • AdChoices
Copyright © 2022 Adobe. All rights reserved.