Movatterモバイル変換


[0]ホーム

URL:


Framework
Messaging

Messaging API

See LicenseNPM InstallFollow PlasmoHQ on TwitterWatch our Live DEMO every FridayJoin our Discord for support and chat about our projects

Plasmo's Messaging API makes communication between different parts of your extension easy. Add a file to yourmessages directory, and Plasmo will handle all the rest. Plasmo Messaging is a declarative, type-safe, functional, promise-based API for sending, relaying, and receiving messages between your extension components.

Installation

1. Install dependency

The@plasmohq/messaging library is kept in a separate repository. You will first have to install it with your package manager.

pnpm install @plasmohq/messaging

2. Create background folder & file

The@plasmohq/messaging library requires the background service worker to live inside abackground/index.ts folder, and all message handlers to live insidebackground/* folders.

If you already have abackground.ts orbackground.js file, you will have to create abackground folder and move your script tobackground/index.ts orbackground/index.js.

If you don't already have abackground folder, create abackground folder and create a new, emptybackground/index.ts orbackground/index.js file.

You will now be able to create new handlers inside thebackground/ subfolder. For example, to create amessages handler with the nameping, you would create abackground/messages/ping.ts. See the rest of the documentation to learn about the different types of handlers available to you, and how to configure them.

At this point, your folder structure might look like this.

New Folder Structure
.├──background├──index.ts└──messages└──ping.ts

3. Generate static types

On compilation, Plasmo will generate static types for all of your message handlers. This will happen automatically if you have the dev server running; it will also happen automatically each time you build. ThesendToBackground andrelayMessage functions both take aname field as part of their params object; thisname field will be statically typed with the names of all of your message handlers.

⚠️

NOTE: Initial Type Error

If you're receiving a type error such as"name" is never, this is because Plasmo needs to compile your handler types. To resolve:

  1. Run the dev server
  2. Restart the TypeScript server in your editor

4. That's all

You have now successfully installed Plasmo's messaging library.

TL;DR

Messaging APIFromToOne-timeLong-lived
Message FlowExt-Pages/CSBGSWYesNo
Relay FlowWebsiteCS/BGSWYesNo
PortsExt-Pages/CSBGSWNoYes
PortsBGSWExt-Pages/CSNoYes
Ports + RelayBGSWWebPageYesYes

Examples

Message Flow

Use the Message Flow to initiate one-time messages between extension pages, tab pages or content scripts with the background service worker. This flow is useful to offload heavy computation to the background service worker or to bypass CORS.

The background service worker is a message hub with REST-style API handlers. To create a message handler, create a ts module in thebackground/messages directory. The file name should be the message name, and the default export should be the handler function:

background/messages/ping.ts
importtype { PlasmoMessaging }from"@plasmohq/messaging"consthandler:PlasmoMessaging.MessageHandler=async (req, res)=> {constmessage=awaitquerySomeApi(req.body.id)res.send({    message  })}exportdefault handler

Extension pages, content scripts, or tab pages can send messages to these handlers using the@plasmohq/messaging library. Since Plasmo Framework orchestrates your handlers behind the scenes, the message names are typed and will enable IntelliSense in your editor:

popup.tsx
import { sendToBackground }from"@plasmohq/messaging"...constresp=awaitsendToBackground({  name:"ping",  body: {    id:123  }})console.log(resp)

To send a message from a content script thats in the main world you'll have to include your extension's id in the request. Your extension's id can be found in chrome's extension manager window once you've built and added it to your browser.

contents/componentInTheMainWorld.tsx
import { sendToBackground }from"@plasmohq/messaging"importtype { PlasmoCSConfig }from"plasmo"exportconstconfig:PlasmoCSConfig= {  matches: ["<all_urls>"],  world:"MAIN"}...constresp=awaitsendToBackground({  name:"ping",  body: {    id:123  },  extensionId:'llljfehhnoeipgngggpomjapaakbkyyy'// find this in chrome's extension manager})console.log(resp)

Relay Flow

⚠️

NOTE: The Relay messaging API is in public alpha preview: expects bugs, incomplete/leaky abstractions, and future API changes. Please report any issues you encounterto us via this link.

The Relay Flow enables communication between a target webpage and a background service worker using a lightweight message handler called a relay. This relay is registered with therelayMessage function in acontent script.

TherelayMessage function abstracts thewindow.postMessage mechanism, registering a listener that checks for messages matching the same origin and forwards them to the background service worker. These messages are then processed by the appropriatemessage flow handlers registered underbackground/messages.

ThesendToBackgroundViaRelay function sends messages through the relay and waits for a response. It generates a unique instance ID for each message to ensure proper handling and response tracking.

You may view the implementation of these functions in theGitHub repository (opens in a new tab).

This method provides an alternative to the"externally_connectable" (opens in a new tab) method described in the Chrome extension documentation.

Setting Up a Relay

To set up a relay, use therelayMessage function in a content script. A content script can have multiple relays. Given theping message handler from the previous example, and the websitewww.plasmo.com:

contents/plasmo.ts
importtype { PlasmoCSConfig }from"plasmo"import { relayMessage }from"@plasmohq/messaging"exportconstconfig:PlasmoCSConfig= {  matches: ["http://www.plasmo.com/*"]// Only relay messages from this domain}relayMessage({  name:"ping"})

In the code of the target webpage (e.g.,plasmo.com), you can send messages using the registered relay usingsendToBackgroundViaRelay as follows:

pages/index.tsx
import { sendToBackgroundViaRelay }from"@plasmohq/messaging"...constresp=awaitsendToBackgroundViaRelay({  name:"ping"})console.log(resp)

To relay messages from contexts wherechrome.runtime is unavailable, you can use therelay function:

sandbox.tsx
import { relayMessage }from"@plasmohq/messaging"relayMessage(  {    name:"ping"  },async (req)=> {console.log("some message was relayed:", req)return {      message:"Hello from sandbox"    }  })

Ports

⚠️

The Port messaging API is in public alpha preview: expects bugs, incomplete/leaky abstractions, and future API changes. Please report any issues you encounterto us via this link.

The Messaging Ports API is a high-level abstraction over the chrome runtime'sport API (opens in a new tab) to establish long-lived connections with the background service worker.

The current implementation focuses on establishing connections to a port listener in the background service worker:

To create a BGSW port handler, create a ts module in thebackground/ports directory. The file name will be the port name, and the default export will be the handler function:

background/ports/mail.ts
importtype { PlasmoMessaging }from"@plasmohq/messaging"consthandler:PlasmoMessaging.PortHandler=async (req, res)=> {console.log(req)res.send({    message:"Hello from port handler"  })}exportdefault handler

In your extension page, get the port using thegetPort utility under the@plasmohq/messaging/port,OR use theusePort hook, keep in mind thatusePort currently relies on React hooks so you will need to use it within a React component. This example shows the usage ofgetPort within a Svelte component:

popup.svelte
<scriptlang="ts">import { getPort }from"@plasmohq/messaging/port"import { onMount, onDestroy }from"svelte"let output=""constmessageListener= (msg)=> {    output= msg  }constmailPort=getPort("mail")onMount(()=> {mailPort.onMessage.addListener(messageListener)  })onDestroy(()=> {mailPort.onMessage.removeListener(messageListener)  })functionhandleSubmit() {mailPort.postMessage({      body: {        hello:"world"      }    })  }</script><div>{output}</div>

Here's an example ofusePort in React, the data will always reflect the latest response from the port handler:

tabs/delta.tsx
import { usePort }from"@plasmohq/messaging/hook"functionDeltaTab() {constmailPort=usePort("mail")return (    <div>      {mailPort.data?.message}      <buttononClick={async ()=> {mailPort.send({            hello:"world"          })        }}>        Send Data      </button>    </div>  )}exportdefault DeltaTab

E2E Type Safety (WIP)

End-to-end request/response body type-safety is in progress at#334 (opens in a new tab). In the meantime, you can use the provided generic types:

background/messages/ping.ts
importtype { PlasmoMessaging }from"@plasmohq/messaging"exporttypeRequestBody= {  id:number}exporttypeResponseBody= {  message:string}consthandler:PlasmoMessaging.MessageHandler<RequestBody,ResponseBody>=async (req, res)=> {console.log(req.body.id)res.send({    message:"Hello from background"  })}exportdefault handler
popup.tsx
import { sendToBackground }from"@plasmohq/messaging"importtype { RequestBody, ResponseBody }from"~background/messages/ping"...constresp=awaitsendToBackground<RequestBody,ResponseBody>({  name:"ping",  body: {    id:123  }})console.log(resp)
Background SWStorage

[8]ページ先頭

©2009-2025 Movatter.jp