0

I have simple website created with vanilla JavaScript and I had create a simple chrome extension.

I want to know is there any way to figure out if my visitors' chrome have my extensions.

This is my manifest.json

{
    "name": "Covid-19 Stats UK",
    "version": "1.0.0",
    "description": "latest covid data of UK",
    "manifest_version": 3,
    "author": "Sampurna Chapagain",
    "action":{
       "default_popup": "index.html",
        "default_title": "Latest Covid Report"
    }
}
Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
  • If your extension adds a hidden element to the page, you could use a `MutationObserver` to check for page modifications made by the extension. You could also look into: [_Check whether user has a Chrome extension installed_](https://stackoverflow.com/questions/6293498/check-whether-user-has-a-chrome-extension-installed) – Mr. Polywhirl Feb 01 '23 at 15:13
  • Does this answer your question? [How can I get installed chrome extensions list with javascript](https://stackoverflow.com/questions/66380739/how-can-i-get-installed-chrome-extensions-list-with-javascript) – Yogi Feb 01 '23 at 15:26

1 Answers1

1

If you control both the extension and the website, two approaches leap to mind: web accessible resources or site-extension messaging.

In this answer I'll be using abcdefghijklmnopqrstuvwxyzabcdef as a placeholder for your extension's ID.

Web accessible resources

Perhaps the simplest way to check if the user has your extension installed is to use XMLHttpRequest or fetch() to try to load a file from the extension. By default, extensions do not expose their resources to websites, but extension authors can selectively expose resources using the "web_accessible_resources" key in the manifest. The following example is for a Manifest V3 extension.

manifest.json

{
  "name": "",
  "version": "",
  "manifest_version": 3,
  "web_accessible_resources": [
    {
      "matches": ["https://example.com/*"],
      "resources": [
        "1x1.png",                   // Expose a single file
        "web-accessible-resources/*" // Or a directory tree
      ]
    }
  ]
}

Then, add the following snippet to your site to check if the extension is installed.

Website JavaScript

const extensionId = "abcdefghijklmnopqrstuvwxyzabcdef";

async function checkExtensionInstalled() {
  try {
    await fetch(`chrome-extension://${extensionId}/1x1.png`);
    return true;
  } catch (e) {
    if (e instanceof TypeError && e.message == 'Failed to fetch') {
      return false;
    } else {
      throw e;
    }
  }
}

// Then in your site's buisness logic, do something like this
checkExtensionInstalled.then(installed => {
  if (installed) {
    console.log("The extension IS installed.");
  } else {
    console.log("The extension is NOT installed.")
  }
});

Messaging

The extension platform allows a website and an extension to communicate directly with each other, but both sides must know about each other in order for this to work.

The following example is adapted from Chrome's official docs.

First, add an "externally_connectable" declaration to your extension's manifest.

manifest.json

  "externally_connectable": {
    "matches": ["https://*.example.com/*"]
  }

Next, update your site's JS to send the extension a message.

Website JavaScript

// The ID of the extension we want to talk to.
const extensionId = "abcdefghijklmnopqrstuvwxyzabcdef";
const messageBody = "Ping";

if (chrome?.runtime?.sendMessage) {
  chrome.runtime.sendMessage(extensionId, messageBody, function(response) {
    console.log("The extension IS installed.", response);
  });
} else {
  console.log("The extension is NOT installed.")
}

Finally, in the extension's background context, add a listener for this message.

background.js

function handleExternalMessage(message, _sender, sendResponse) {
  if (message === "Ping") {
    sendResponse("Pong");
  };
}

chrome.runtime.onMessageExternal.addListener(handleExternalMessage);
Simeon Vincent
  • 373
  • 1
  • 11
  • tnx for the answer, I have question what should I put `a..z` part `await fetch(`chrome-extension://a...z/1x1.png`);` and `"matches": ["https://example.com/*"],` this for `example` – miladjurablu Feb 05 '23 at 06:17
  • The "a..z" was supposed to be a placeholder for your extension's ID. I've updated the code sample to be more obvious. The text before the `"matches"` line should be added to your manifest.json file. – Simeon Vincent Feb 06 '23 at 19:03