guocaoyi / create-chrome-ext

🍺 Scaffolding your Chrome extension! Boilerplates: react \ vue \ svelte \ solid \ preact \ alpine \ lit \ stencil \ inferno \ vanilla
MIT License
1.44k stars 107 forks source link

Quality of Life Feature Request: Message Passing Example #17

Closed pascalwacker closed 9 months ago

pascalwacker commented 1 year ago

I'm trying to have a plugin, that will add some additional information it fetches from an API to DOM elements on the site.

In addition I'd like to have a "summary" (like the count of elements it found on the page, etc.) available in the popup, as well as an option to dissable the plugin for a certain domain.

This means I need to pass data between the content script that is doing the DOM manipulation as well as the popup. After some banging my head against the desk and finding a lot of v2 solutions, I finally found this tutorial: https://plainenglish.io/blog/how-to-send-data-between-chrome-extension-scripts-1182ce67b659 and https://www.freecodecamp.org/news/chrome-extension-message-passing-essentials/

It would be wonderful to have something like this included in the default state after running create-chrome-ext to get started. If you want to keep the basic version it creates clean, maybe a link to those two articles in the read me would be nice. The first one basically tells you how to send messages with manifest v3, the second one explains the concept a bit more and has more examples, however they're for manifest v2.

guocaoyi commented 1 year ago

advance features in planning...

includes:

  1. basic message event
  2. truely out of box

release this weekend or next!

marjan2k commented 1 year ago

Hey, is there a sample of message event anywhere?

clairefro commented 11 months ago

I'd love to see an example as well - been hacking away for a while to no success

clairefro commented 11 months ago

example of getting highlighted text from the DOM in active tab on button click. Popup sends a message to content script. Not sure if it's right practice, but sort of working

content/index.js

console.info('chrome-ext template-react-js content script')

function getHighlightedText() {
  var selection = window.getSelection().toString();
  return selection;
}

chrome.runtime.onMessage.addListener(
  function (request, sender, sendResponse) {
    // Add message listeners
    if (request["type"] == 'GET_SELECTED') {
      const highlightedText = getHighlightedText()
      sendResponse(highlightedText);
    }
    return true; // this make sure sendResponse will work asynchronously
  }
);

export { }

Popup.jsx

import { useState, useEffect } from 'react';
import icon from '../../assets/logo.png';

const Popup = () => {
  const [highlightedText, setHighlightedText] = useState("");

  const handleClick = () => {
    chrome.tabs.query({ active: true, currentWindow: true }, function (tabs) {
      chrome.tabs.sendMessage(tabs[0].id, { type: "GET_SELECTED" }, function (response) {
        setHighlightedText(response)
      });
    });
  };

  return (
    <div>
      <img src={icon} alt="extension icon" />
      <div>
        <h1>Highlighted Text</h1>
        <button onClick={handleClick}>Get highlight</button>
        <p>{highlightedText}</p>
      </div>
    </div >
  )
}

export default Popup;

manifest.json

{
    ...,
    permissions: ["tabs", "activeTab"]
}

still get this error sometimes:

Unchecked runtime.lastError: Could not establish connection. Receiving end does not exist.
clairefro commented 11 months ago

Above code seems to be working now after restarting dev server, to apply manifest file changes

Here's a snapshot of working app with messaging: snapshot

Popup logic in component called Main.jsx

guocaoyi commented 9 months ago

0.9.0 released!