diff --git a/files/en-us/mozilla/add-ons/webextensions/native_manifests/index.md b/files/en-us/mozilla/add-ons/webextensions/native_manifests/index.md index 0737d1d64902f7a..160eee5e76669a9 100644 --- a/files/en-us/mozilla/add-ons/webextensions/native_manifests/index.md +++ b/files/en-us/mozilla/add-ons/webextensions/native_manifests/index.md @@ -150,11 +150,11 @@ For example, here's the content of the `ping_pong.json` manifest file for the `p "description": "Example host for native messaging", "path": "/path/to/native-messaging/app/ping_pong.py", "type": "stdio", - "allowed_extensions": ["ping_pong@example.org"] + "allowed_extensions": ["native-messaging@mozilla.org"] } ``` -This allows the extension with the ID `ping_pong@example.org` to connect by passing the name `ping_pong` into the relevant {{WebExtAPIRef("runtime")}} API function. The native application is at `/path/to/native-messaging/app/ping_pong.py`. +This allows the extension with the ID `native-messaging@mozilla.org` to connect by passing the name `ping_pong` into the relevant {{WebExtAPIRef("runtime")}} API function. The native application is at `/path/to/native-messaging/app/ping_pong.py`. ## Managed storage manifests diff --git a/files/en-us/mozilla/add-ons/webextensions/native_messaging/index.md b/files/en-us/mozilla/add-ons/webextensions/native_messaging/index.md index b75b3cdbe66ed84..b3cfe54d741adc6 100644 --- a/files/en-us/mozilla/add-ons/webextensions/native_messaging/index.md +++ b/files/en-us/mozilla/add-ons/webextensions/native_messaging/index.md @@ -5,42 +5,46 @@ page-type: guide sidebar: addonsidebar --- -**Native messaging** enables an extension to exchange messages with a native application, installed on the user's computer. The native messaging serves the extensions without additional accesses over the web. +Native messaging enables an extension to exchange messages with a native application installed on the user's computer. You can use this feature to retrieve details from a local app, rather than accessing the web. -Password managers: The native application manages, stores, and encrypts passwords. Then the native application communicates with the extension to populate web forms. +For example, in a password manager, the native application manages, stores, and encrypts passwords. The extension then communicates with the native application to save and retrieve details to populate web forms. -Native messaging also enables extensions to access resources that are not accessible through WebExtension APIs (e.g., particular hardware). +Native messaging also enables extensions to access resources not accessible through WebExtension APIs (e.g., specific hardware). -The native application is not installed or managed by the browser. The native application is installed, using the underlying operating system's installation machinery. Create a JSON file called the "host manifest" or "app manifest". Install the JSON file in a defined location. The app manifest file will describe how the browser can connect to the native application. +The native application isn't installed or managed by the browser. The native application must be installed using the operating system's usual installation mechanism. -The extension must request the `"nativeMessaging"` [permission](/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/permissions) or [optional permission](/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/optional_permissions) in the `manifest.json` file. Also, the native application must grant permission for the extension by including the ID in the `"allowed_extensions"` field of the app manifest. +## Overview -After installing, the extension can exchange JSON messages with the native application. Use a set of functions in the {{WebExtAPIRef("runtime")}} API. On the native app side, messages are received using standard input (`stdin`) and sent using standard output (`stdout`). +A JSON file called the "host manifest" or "app manifest" describes how the browser can connect to the native application. The local app installs this JSON file in an operating system-specific location. -![Application flow: the native app JSON file resides on the users computer, providing resource information to the native application. The read and write functions of the native application interact with the browser extension's runtime events.](native-messaging.png) +The extension must request the `"nativeMessaging"` [permission](/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/permissions) or [optional permission](/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/optional_permissions) in its `manifest.json` file. Also, the native application must grant permission for the extension by including the extension's ID in the `"allowed_extensions"` field of the app manifest. -Support for native messaging in extensions is mostly compatible with Chrome, with two main differences: +The extension exchanges JSON messages with the native application using functions in the {{WebExtAPIRef("runtime")}} API. On the native app side, messages are received using standard input (`stdin`) and sent using standard output (`stdout`). -- The app manifest lists `allowed_extensions` as an array of app IDs, while Chrome lists `allowed_origins`, as an array of `"chrome-extension"` URLs. +![Application flow: the native app JSON file resides on the user's computer, providing resource information to the native application. The read and write functions of the native application interact with the browser extension's runtime events.](native-messaging.png) + +Support for native messaging in extensions is mainly compatible with Chrome, with two main differences: + +- The app manifest lists `allowed_extensions` as an array of app IDs, while Chrome lists `allowed_origins` as an array of `"chrome-extension"` URLs. - The app manifest is stored in a different location [compared to Chrome](https://developer.chrome.com/docs/apps/nativeMessaging/#native-messaging-host-location). -There's a complete example in the [`native-messaging` directory](https://github.com/mdn/webextensions-examples/tree/main/native-messaging) of the `webextensions-examples` repository on GitHub. Most example code in this article is taken from that example. +There's a complete example in the [`native-messaging` directory](https://github.com/mdn/webextensions-examples/tree/main/native-messaging) of the `webextensions-examples` repository on GitHub. Most of the code in this article is from that example. ## Setup ### Extension manifest -Extension communicating with a native application: +To enable communication with a native application, the extension's [`manifest.json`](/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json) file must: -- Set the `"nativeMessaging"` [permission](/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/permissions) or [optional permission](/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/optional_permissions) in the [`manifest.json`](/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json) file. -- Specify your add-on ID explicitly. Use the [`browser_specific_settings`](/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/browser_specific_settings) manifest key. (The app's manifest will identify the set of extensions that allow connecting to the IDs). +- Set the `"nativeMessaging"` [permission](/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/permissions) or [optional permission](/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/optional_permissions). +- Specify an add-on ID using the [`browser_specific_settings`](/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/browser_specific_settings) manifest key. (The native app's manifest uses this ID to identify that the extension is allowed to connect.) Example `manifest.json` file: ```json { "description": "Native messaging example add-on", - "manifest_version": 2, + "manifest_version": 3, "name": "Native messaging example", "version": "1.0", "icons": { @@ -49,7 +53,10 @@ Example `manifest.json` file: "browser_specific_settings": { "gecko": { - "id": "ping_pong@example.org", + "id": "native-messaging@mozilla.org", + "data_collection_permissions": { + "required": ["none"] + }, "strict_min_version": "50.0" } }, @@ -58,7 +65,7 @@ Example `manifest.json` file: "scripts": ["background.js"] }, - "browser_action": { + "action": { "default_icon": "icons/message.svg" }, @@ -67,16 +74,13 @@ Example `manifest.json` file: ``` > [!NOTE] -> Chrome does not support the [browser_specific_settings](/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/browser_specific_settings) key. You will need to use another manifest without this key to install an equivalent WebExtension on Chrome. See [Chrome incompatibilities below](#chrome_incompatibilities). - -> [!NOTE] -> When using optional permission, check that permission has been granted and, where necessary, request permission from the user with the {{WebExtAPIRef("permissions")}} API before communicating with the native application. +> When using optional permission, before communicating with the native application, check that permission is granted and, where necessary, request permission from the user with the {{WebExtAPIRef("permissions")}} API. ### App manifest -The app manifest describes to the browser how it can connect to the native application. +The app manifest describes how the browser can connect to the native application. -The app manifest file must be installed along with the native application. The browser reads and validates app manifest files, but it does not install or manage them. The security model for when and how these files are installed and updated is much more like that for native applications than that for extensions using WebExtension APIs. +The browser reads and validates app manifest files, but it does not install or manage them; native applications must install them. This requirement stems from the security model for when and how these files are installed and updated, which is much more like that for native applications than for extensions using WebExtension APIs. For details of native app manifest syntax and location, see [Native manifests](/en-US/docs/Mozilla/Add-ons/WebExtensions/Native_manifests). @@ -88,22 +92,22 @@ For example, here's a manifest for the `"ping_pong"` native application: "description": "Example host for native messaging", "path": "/path/to/native-messaging/app/ping_pong.py", "type": "stdio", - "allowed_extensions": ["ping_pong@example.org"] + "allowed_extensions": ["native-messaging@mozilla.org"] } ``` -This allows the extension whose ID is `"ping_pong@example.org"` to connect, by passing the name `"ping_pong"` into the relevant {{WebExtAPIRef("runtime")}} API function. The application itself is at `"/path/to/native-messaging/app/ping_pong.py"`. +This manifest allows the extension with the ID `"native-messaging@mozilla.org"` to connect by passing the name `"ping_pong"` to the relevant {{WebExtAPIRef("runtime")}} API function. The application itself is at `"/path/to/native-messaging/app/ping_pong.py"`. > [!NOTE] -> Chrome identifies allowed extensions with another key: `allowed_origins`, using the ID of the WebExtension. Refer to [Chrome documentation for more details](https://developer.chrome.com/docs/apps/nativeMessaging/#native-messaging-host) and see [Chrome incompatibilities below](#chrome_incompatibilities). +> Chrome identifies allowed extensions with another key: `allowed_origins`, using the ID of the WebExtension. Refer to [Chrome documentation for more details](https://developer.chrome.com/docs/apps/nativeMessaging/#native-messaging-host) and see the [Chrome incompatibilities](#chrome_incompatibilities) section. ### Windows setup -As an example, you can also refer to [the readme on the native messaging extension on GitHub](https://github.com/SphinxKnight/webextensions-examples/tree/master/native-messaging#windows-setup). If you want to check your local setup after having forked this repository on a Windows machine, you may run `check_config_win.py` to troubleshoot some issues. +This section describes the window-specific setup requirements. These requirements are also described in [the readme of the native messaging extension on GitHub](https://github.com/SphinxKnight/webextensions-examples/tree/master/native-messaging#windows-setup). After forking this repository on a Windows machine, you can check your setup by running `check_config_win.py`. #### App manifest -In the example above, the native application is a Python script. It can be difficult to get Windows to run Python scripts reliably in this way, so an alternative is to provide a `.bat` file, and link to that from the application's manifest: +In the example extension, the native application is a Python script. It can be challenging to get Windows to run Python scripts reliably. An alternative is to provide a `.bat` file, and link to that from the application's manifest: ```json { @@ -111,7 +115,7 @@ In the example above, the native application is a Python script. It can be diffi "description": "Example host for native messaging", "path": "c:\\path\\to\\native-messaging\\app\\ping_pong_win.bat", "type": "stdio", - "allowed_extensions": ["ping_pong@example.org"] + "allowed_extensions": ["native-messaging@mozilla.org"] } ``` @@ -127,46 +131,46 @@ python -u "c:\\path\\to\\native-messaging\\app\\ping_pong.py" #### Registry -The browser finds the extension based on registry keys which are located in a specific location. You need to add them either programmatically with your final application or manually if you are using the example from GitHub. For more details, refer to [Manifest location](/en-US/docs/Mozilla/Add-ons/WebExtensions/Native_manifests#manifest_location). +The browser finds the extension based on registry keys located in a specific location. You need to add them either programmatically with your final application or manually if you are using the example from GitHub. For more details, refer to [Manifest location](/en-US/docs/Mozilla/Add-ons/WebExtensions/Native_manifests#manifest_location). -Following with the `ping_pong` example, if using Firefox (see [this page for Chrome](https://developer.chrome.com/docs/apps/nativeMessaging/#native-messaging-host-location)), one of the two registry entries should be created for the messaging to work: +For the `ping_pong` example, when using Firefox (see [this page for Chrome](https://developer.chrome.com/docs/apps/nativeMessaging/#native-messaging-host-location)), you must create one of these registry entries for the messaging to work: - `HKEY_CURRENT_USER\Software\Mozilla\NativeMessagingHosts\ping_pong` - `HKEY_LOCAL_MACHINE\Software\Mozilla\NativeMessagingHosts\ping_pong` -The default value for the key should be the path to the _application_ manifest: ex. `C:\Users\\webextensions-examples\native-messaging\app\ping_pong.json`. +The default value for the key must be the path to the _application_ manifest: e.g., `C:\Users\\webextensions-examples\native-messaging\app\ping_pong.json`. > [!NOTE] -> If you base your work on the example located on GitHub, please read [this part of the readme](https://github.com/SphinxKnight/webextensions-examples/tree/master/native-messaging#windows-setup) and check the output of `check_config_win.py` before installing the WebExtension on your browser. +> If you base your work on the GitHub example, read [this part of the readme](https://github.com/SphinxKnight/webextensions-examples/tree/master/native-messaging#windows-setup) and check the output of `check_config_win.py` before installing the extension in your browser. ## Exchanging messages -Given the above setup, an extension can exchange JSON messages with a native application. +When the setup is complete, an extension can exchange JSON messages with a native application. ### Extension side -Native messaging cannot directly be used in content scripts. You must [do it indirectly via background scripts](/en-US/docs/Mozilla/Add-ons/WebExtensions/Content_scripts#communicating_with_background_scripts). +An extension cannot use native messaging in content scripts. It must [do it indirectly using background scripts](/en-US/docs/Mozilla/Add-ons/WebExtensions/Content_scripts#communicating_with_background_scripts). -There are two patterns to use here: **connection-based messaging** and **connectionless messaging**. +There are two patterns available: **connection-based messaging** and **connectionless messaging**. #### Connection-based messaging -With this pattern you call {{WebExtAPIRef("runtime.connectNative()")}}, passing the name of the application (the value of the `"name"` property in the app's manifest). This launches the application if it is not already running and returns a {{WebExtAPIRef("runtime.Port")}} object to the extension. +With this pattern, your extension calls {{WebExtAPIRef("runtime.connectNative()")}}, passing the name of the application (the value of the `"name"` property in the app's manifest). This API launches the application if it's not running and returns a {{WebExtAPIRef("runtime.Port")}} object to the extension. Two arguments are passed to the native app when it starts: - The complete path to the app manifest. -- (new in Firefox 55) the ID (as given in the [browser_specific_settings](/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/browser_specific_settings) `manifest.json` key) of the add-on that started it. +- The ID (as given in the [browser_specific_settings](/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/browser_specific_settings) `manifest.json` key) of the extension that started it. > [!NOTE] > Chrome handles the passed arguments differently: > -> - On Linux and Mac, Chrome passes _one_ argument: the origin of the extension that started it (in the form `chrome-extension://[extensionID]`). This enables the app to identify the extension. +> - On Linux and Mac, Chrome passes _one_ argument: the origin of the extension that started it (in the form `chrome-extension://[extensionID]`). This information enables the app to identify the extension. > - On Windows, Chrome passes _two_ arguments: the first is the origin of the extension, and the second is a handle to the Chrome native window that started the app. -The application stays running until the extension calls `Port.disconnect()` or the page that connected to it is closed. +The application runs until the extension calls `Port.disconnect()` or the page that connected to it is closed. -To send messages using `Port`, call its `postMessage()` function, passing the JSON message to send. To listen for messages using `Port`, add the listener using its `onMessage.addListener()` function. +To send messages using `Port`, the extension calls `postMessage()` passing the JSON message to send. To listen for messages on `Port`, the extension adds a listener with `onMessage.addListener()`. Here's an example background script that establishes a connection with the `"ping_pong"` app, listens for messages from it, then sends it a `"ping"` message whenever the user clicks the browser action: @@ -186,7 +190,7 @@ port.onMessage.addListener((response) => { /* On a click on the browser action, send the app a message. */ -browser.browserAction.onClicked.addListener(() => { +browser.action.onClicked.addListener(() => { console.log("Sending: ping"); port.postMessage("ping"); }); @@ -196,18 +200,18 @@ browser.browserAction.onClicked.addListener(() => { With this pattern you call {{WebExtAPIRef("runtime.sendNativeMessage()")}}, passing it: -- the name of the application -- the JSON message to send -- optionally, a callback. +- The name of the application. +- The JSON message to send. +- Optionally, a callback. -A new instance of the app is created for each message. The app passes two arguments when starting: +This call creates a new instance of the app for each message. The app passes two arguments when starting: -- the complete path to the app manifest -- (new in Firefox 55) the ID (as given in the [browser_specific_settings](/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/browser_specific_settings) manifest.json key) of the add-on that started it. +- The complete path to the app manifest. +- The ID (as given in the [browser_specific_settings](/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/browser_specific_settings) manifest.json key) of the extension that started it. -The first message sent by the app is treated as a response to the `sendNativeMessage()` call, and will be passed into the callback. +The app treats the first message sent as a response to the `sendNativeMessage()` call, and the API passes it into the callback. -Here's the example above, rewritten to use `runtime.sendNativeMessage()`: +Here's the connection-based example rewritten to use `runtime.sendNativeMessage()`: ```js function onResponse(response) { @@ -221,7 +225,7 @@ function onError(error) { /* On a click on the browser action, send the app a message. */ -browser.browserAction.onClicked.addListener(() => { +browser.action.onClicked.addListener(() => { console.log("Sending: ping"); let sending = browser.runtime.sendNativeMessage("ping_pong", "ping"); sending.then(onResponse, onError); @@ -230,13 +234,11 @@ browser.browserAction.onClicked.addListener(() => { ### App side -On the application side, you use standard input to receive messages and standard output to send them. - -Each message is serialized using JSON, UTF-8 encoded and is preceded with an unsigned 32-bit value containing the message length in native byte order. +The application uses standard input to receive messages and standard output to send them. It must serialize each message as UTF-8 encoded JSON, preceded by an unsigned 32-bit value containing the message length in native byte order. -The maximum size of a single message from the application is 1 MB. The maximum size of a message sent to the application is 4 GB. +The native application can send messages of up to 1 MB and receive messages of up to 4 GB. -You can quickly get started sending and receiving messages with this NodeJS code, `nm_nodejs.mjs`: +This NodeJS code, `nm_nodejs.mjs`, is an example of sending and receiving messages: ```js #!/usr/bin/env -S /full/path/to/node @@ -282,7 +284,7 @@ while (true) { } ``` -Here's another example written in Python. It listens for messages from the extension. Note that the file has to be executable on Linux. If the message is `"ping"`, then it responds with a message `"pong"`. +Here's another example written in Python. It listens for messages from the extension. Note that the file has to be executable on Linux. If the message is `"ping"`, it responds with `"pong"`. This is the Python 2 version: @@ -290,8 +292,8 @@ This is the Python 2 version: #!/usr/bin/env -S python2 -u # Note that running python with the `-u` flag is required on Windows, -# in order to ensure that stdin and stdout are opened in binary, rather -# than text, mode. +# to ensure that stdin and stdout are opened in binary, rather than +# text, mode. import json import sys @@ -306,7 +308,7 @@ def get_message(): message = sys.stdin.read(message_length) return json.loads(message) -# Encode a message for transmission, given its content. +# Encode a message for transmission. def encode_message(message_content): # https://docs.python.org/3/library/json.html#basic-usage # To get the most compact JSON representation, you should specify @@ -329,14 +331,14 @@ while True: send_message(encode_message("pong")) ``` -In Python 3, the received binary data must be decoded into a string. The content to be sent back to the addon must be encoded into binary data using a struct: +In Python 3, the code must decode the received binary data into a string. The content the code sends back to the extension must be encoded into binary data using a struct: ```python #!/usr/bin/env -S python3 -u # Note that running python with the `-u` flag is required on Windows, -# in order to ensure that stdin and stdout are opened in binary, rather -# than text, mode. +# to ensure that stdin and stdout are opened in binary, rather than +# text, mode. import sys import json @@ -351,8 +353,7 @@ def getMessage(): message = sys.stdin.buffer.read(messageLength).decode('utf-8') return json.loads(message) -# Encode a message for transmission, -# given its content. +# Encode a message for transmission. def encodeMessage(messageContent): # https://docs.python.org/3/library/json.html#basic-usage # To get the most compact JSON representation, you should specify @@ -376,70 +377,83 @@ while True: ## Closing the native app -If you connected to the native application using `runtime.connectNative()`, then it stays running until the extension calls `Port.disconnect()` or the page that connected to it is closed. If you started the native application by sending `runtime.sendNativeMessage()`, then it is closed after it has received the message and sent a response. +If the extension connected to the native application using `runtime.connectNative()`, then the native application runs until the extension calls `Port.disconnect()` or the page that connected to it is closed. If the extension started the native application using `runtime.sendNativeMessage()`, the native application is closed after it sends a response. To close the native application: - On \*nix systems like macOS and Linux, the browser sends `SIGTERM` to the native application, then `SIGKILL` after the application has had a chance to exit gracefully. These signals propagate to any subprocesses unless they break away into a new process group. -- On Windows, the browser puts the native application's process into a [Job object](https://learn.microsoft.com/en-us/windows/win32/procthread/job-objects) and kills the job. If the native application launches additional processes and wants them to remain open after the native application is killed, then the native application must launch the additional process with the [`CREATE_BREAKAWAY_FROM_JOB`](https://learn.microsoft.com/en-us/windows/win32/procthread/process-creation-flags) flag, such as by using `CreateProcess`. +- On Windows, the browser puts the native application's process into a [Job object](https://learn.microsoft.com/en-us/windows/win32/procthread/job-objects) and kills the job. If the native application launches additional processes and wants them to remain open after Windows kills the native application, then the native application must launch the processes with the [`CREATE_BREAKAWAY_FROM_JOB`](https://learn.microsoft.com/en-us/windows/win32/procthread/process-creation-flags) flag, such as by using `CreateProcess`. ## Troubleshooting -If something goes wrong, check the [browser console](https://extensionworkshop.com/documentation/develop/debugging/#viewing_log_output). If the native application sends any output to stderr, the browser will redirect it to the browser console. So if you've got as far as launching the native application, you will see any error messages it emits. +If native messaging doesn't work as expected, check the [browser console](https://extensionworkshop.com/documentation/develop/debugging/#viewing_log_output). If the native application sends any output to stderr, the browser redirects it to the browser console. If the extension launched the native application, you see any error messages it emits. -If you haven't managed to run the application, you should see an error message giving you a clue about the problem. +If the extension hasn't managed to run the application, you see an error message providing information about the problem. ```plain "No such native application " ``` +For this error: + - Check that the name passed to `runtime.connectNative()` matches the name in the app manifest -- macOS/Linux: check that name of the app manifest is `.json`. -- macOS/Linux: check the native application's manifest file location as mentioned [in the native manifests reference](/en-US/docs/Mozilla/Add-ons/WebExtensions/Native_manifests#macos). -- Windows: check that the registry key is in the correct place, and that its name matches the name in the app manifest. -- Windows: check that the path given in the registry key points to the app manifest. +- On macOS/Linux, check that the: + - Name of the app manifest is `.json`. + - Native application's manifest file location is as mentioned [in the native manifests reference](/en-US/docs/Mozilla/Add-ons/WebExtensions/Native_manifests#macos). +- On Windows, check that the: + - Registry key is in the correct place, and its name matches the name in the app manifest. + - Path given in the registry key points to the app manifest. + +```plain +"Error: Invalid application " +``` - ```plain - "Error: Invalid application " - ``` +For this error: - Check that the application's name contains no invalid characters. - ```plain +```plain "'python' is not recognized as an internal or external command, ..." - ``` +``` + +For this error: - Windows: if your application is a Python script, check that you have Python installed and have your path set up for it. - ```plain - "File at path does not exist, or is not executable" - ``` +```plain +"File at path does not exist, or is not executable" +``` + +If you see this, then the app manifest has been found. Check that: + +- The "path" in the app's manifest is correct. +- On Windows: you've escaped the path separators (`"c:\\path\\to\\file"`). +- The app is at the location pointed to by the `"path"` property in the app's manifest. +- The app is executable. -- If you see this, then the app manifest has been found successfully. -- Check that the "path" in the app's manifest is correct. -- Windows: check that you've escaped the path separators (`"c:\\path\\to\\file"`). -- Check that the app is at the location pointed to by the `"path"` property in the app's manifest. -- Check that the app is executable. +```plain +"This extension does not have permission to use native application " +``` - ```plain - "This extension does not have permission to use native application " - ``` +For this error: - Check that the `"allowed_extensions"` key in the app manifest contains the add-on's ID. - ```plain - "TypeError: browser.runtime.connectNative is not a function" - ``` +```plain +"TypeError: browser.runtime.connectNative is not a function" +``` + +For this error: - Check that the extension has the `"nativeMessaging"` permission. - ```plain - "[object Object] NativeMessaging.jsm:218" - ``` +```plain +"[object Object] NativeMessaging.jsm:218" +``` -- There was a problem starting the application. +There was a problem starting the application. ## Chrome incompatibilities -There are a number of differences between browsers that affect native messaging in web extensions, including the arguments passed to the native app, location of the manifest file, etc. -These differences are discussed in [Chrome incompatibilities > Native messaging](/en-US/docs/Mozilla/Add-ons/WebExtensions/Chrome_incompatibilities#native_messaging). +There are some differences between browsers that affect native messaging in web extensions, including the arguments passed to the native app, the location of the manifest file, etc. +The [Native messaging section of the Chrome incompatibilities article](/en-US/docs/Mozilla/Add-ons/WebExtensions/Chrome_incompatibilities#native_messaging) describes these differences.