Messaging

Typed wrappers around chrome.runtime.sendMessage and chrome.tabs.sendMessage. Use these for popup ↔ background ↔ content script communication.

Register a handler (background)

The background worker is the central message hub. Register a handler that processes incoming messages from all surfaces.

import { registerMessageHandler } from "@/shared/messaging";

registerMessageHandler(async (message) => {
  if (message.type === "PING") return { ok: true, data: "pong" };
  if (message.type === "FETCH_DATA") {
    const data = await fetchFromAPI();
    return { ok: true, data };
  }
  return { ok: false, error: "Unsupported message" };
});

Send from popup or side panel

import { sendRuntimeMessage } from "@/shared/messaging";

const response = await sendRuntimeMessage({ type: "PING" });
// { ok: true, data: "pong" }

Send to a content script

Before sending, verify the tab is injectable and the content script is loaded.

import {
  sendTabMessage,
  getActiveInjectableTab,
  ensureContentScriptReady,
} from "@/shared/messaging";

const tab = await getActiveInjectableTab();
await ensureContentScriptReady(tab.id);
const response = await sendTabMessage(tab.id, { type: "EXTRACT_PAGE" });

Generated message types

The background handler already knows about PING, GET_ACTIVE_TAB_INFO, and CONTENT_UI_MOUNTED. Add your own message types for product logic — define them as string literals and handle them in the background handler.