create app using manifest - not matching URL

236 views
Skip to first unread message

Gordon Stewart

unread,
Jan 13, 2023, 4:25:55 AM1/13/23
to Chromium Extensions
Hello. Is this the correct place for a discussion on Google chrome apps (extensions).

I'm following the manifest tutorials I can find however can't make it do whatever I want.

What I'm getting:- it shows my hello.html file on ALL / any URL the person uses.

what I want

- Matches URL - YES - show hello.html (welcome message), also shows a button to activate another script

- any other URL - show a different message (tell people about my script/app ), do not show the button.


so far I've got this
 "action": {
        "default_popup": "hello.html",
       "matches":["https://*.MYDOMAIN.COM/?"]
    },


but it displays hello.html on ANY tab / URL I'm on.

Stefan Van Damme

unread,
Jan 13, 2023, 8:31:05 AM1/13/23
to Chromium Extensions, gordo...@gmail.com
Hi there,

Google Chrome app is deprecated. See this developer page:
Important: Chrome will be removing support for Chrome Apps on all platforms. Chrome browser and the Chrome Web Store will continue to support extensions. Read the announcement and learn more about migrating your app.

If you mean to create a Chrome extension with Manifest v3. If you are a new developer see this tutorial:

|| - Matches URL - YES - show hello.html (welcome message), also shows a button to activate another script
|| - any other URL - show a different message (tell people about my script/app ), do not show the button.

You can use the service workers (background) to detect the currently open tab URL. And then set up a new popup. For example:
chrome.action.setPopup({tabId: tab.id, popup:"palette.html"});
And another tab URL, this page.
chrome.action.setPopup({tabId: tab.id, popup:"popup.html"});

An example is in my Turn Off the Lights browser extension, I use the double click -> the mini settings panel. And if the user is on a Chrome page, the error panel:

Thanks,

wOxxOm

unread,
Jan 13, 2023, 9:23:28 AM1/13/23
to Chromium Extensions, stefa...@gmail.com, gordo...@gmail.com
Chrome extensions don't support `matches` for `action`.

The documentation shows how you can emulate this behavior:
Don't forget to add "declarativeContent" to "permissions" and the necessary "host_permissions" in manifest.json.

Stefan Van Damme

unread,
Jan 13, 2023, 9:42:54 AM1/13/23
to Chromium Extensions, Stefan Van Damme, gordo...@gmail.com
Hi gordo..,

My code sample does not need any additional permission. Only activeTab to detect the currently open tab URL.
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
    if (tab.url = "https://www.stefanvd.net") {
        chrome.browserAction.setPopup({
            tabId: tabId,
            popup: 'panel1.html'
        });
    } else {
        chrome.browserAction.setPopup({
            tabId: tabId,
            popup: 'panel2.html'
        });
    }
});

Thanks,
Stefan vd

wOxxOm

unread,
Jan 13, 2023, 9:49:18 AM1/13/23
to Chromium Extensions, stefa...@gmail.com, gordo...@gmail.com
chrome.tabs.onUpdated runs on every update of every tab which can happen thousands of times a day, thus wasting CPU/resources/battery to restart the background script.

The declarativeContent permission takes care of that by itself without starting the background script. It doesn't have a warning. The host permissions are optional. It's possible to use "activeTab" permission instead, depending on the workflow.

wOxxOm

unread,
Jan 13, 2023, 9:52:02 AM1/13/23
to Chromium Extensions, wOxxOm, stefa...@gmail.com, gordo...@gmail.com
Also, chrome.tabs.onUpdated won't see `tab.url` unless you have `tabs` permission, which shows an installation warning, or host permissions, or you already clicked the icon, which defeats the purpose of switching the popup before the click.

Stefan Van Damme

unread,
Jan 13, 2023, 10:20:05 AM1/13/23
to Chromium Extensions, gordo...@gmail.com
Hi there,

|| won't see `tab.url` 
I converted the code from Manifest V2 to Manifest V3. And yes it must be permissions": [ "tabs" ] in the manifest.json. Also here is the new Manifest V3 code (with typo fix):
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
    console.log("tab url =",tab.url);
    if (tab.url == "https://www.stefanvd.net/") {
        console.log("panel 1")
        chrome.action.setPopup({
            tabId: tabId,
            popup: 'popup1.html'
        });
    } else {
        console.log("panel 2")
        chrome.action.setPopup({
            tabId: tabId,
            popup: 'popup2.html'
        });
    }
});

Thanks,
Stefan vd


Gordon Stewart

unread,
Jan 13, 2023, 8:42:34 PM1/13/23
to Chromium Extensions, stefa...@gmail.com, Gordon Stewart
Hi again - its not going.

Has anyone got a good tutorial with the *BARE MINIMUM* code to get this thing going.


BOOK: Wheres spot by Eric Hill -  see Spot Run, See Spot sit etc.

I do not want to read War & Peace with 1000's of pages and only need a handful of lines of code that i actually need..

Heres what i have so far

manifest.json
---------------------------------


{
  "manifest_version": 3,
  "name": "Ktest",
  "version": "1.0",

  "action": {
    "default_popup": "popup.html"
  },

 "permissions": [
     "tabs",
     "activeTab",
     "declarativeContent"
],

  "background": {
  "service_worker": "background.js"
  }

}

----------------------------------

popup.html
---------------------

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  </head>
  <body>
    <template id="li_template">
      <li>
        <a>
          <h3 class="title">Tab Title</h3>
          <p class="pathname">Tab Pathname</p>
        </a>
      </li>
    </template>

    <h1>Google Dev Docs</h1>
    <button>Group Tabs</button>
    <ul></ul>

    <script src="./popup.js" type="module"></script>
  </body>
</html>

---------------------

background.js

-------------------------

console.log("Page location is " + window.location.href);

-------------------------


ERRORS RECEIVED with the above codes:

1) Service worker registration failed. Status code: 15
2) Uncaught ReferenceError: window is not defined

(Ive googled & cannot see anything with "service code 15" explanation.)

================================================


NOW - using the advice received so far in this thread:

https://developer.chrome.com/docs/extensions/mv3/getstarted/tut-tabs-manager/

popup.html
------------------------------------

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  </head>
  <body>
    <template id="li_template">
      <li>
        <a>
          <h3 class="title">Tab Title</h3>
          <p class="pathname">Tab Pathname</p>
        </a>
      </li>
    </template>

    <h1>Google Dev Docs</h1>
    <button>Group Tabs</button>
    <ul></ul>

    <script src="./popup.js" type="module"></script>
  </body>
</html>

------------------------------------

popup.js
-----------------------------------
const tabs = await chrome.tabs.query({
  url: [
    "https://*.domain.com",
  ],
});


const collator = new Intl.Collator();
tabs.sort((a, b) => collator.compare(a.title, b.title));

const template = document.getElementById("li_template");
const elements = new Set();
for (const tab of tabs) {
  const element = template.content.firstElementChild.cloneNode(true);

  const title = tab.title.split("-")[0].trim();
  const pathname = new URL(tab.url).pathname.slice("/docs".length);

  element.querySelector(".title").textContent = title;
  element.querySelector(".pathname").textContent = pathname;
  element.querySelector("a").addEventListener("click", async () => {
    // need to focus window as well as the active tab
    await chrome.tabs.update(tab.id, { active: true });
    await chrome.windows.update(tab.windowId, { focused: true });
  });

  elements.add(element);
}
document.querySelector("ul").append(...elements);

-----------------------------------

manifest.json
---------------------------------------

{
  "manifest_version": 3,
  "name": "K TRIPPER",
  "version": "1.0",
  "icons": {
    "16": "images/icon-16.png",
    "32": "images/icon-32.png",
    "48": "images/icon-48.png",
    "128": "images/icon-128.png"
  },

    "action": {
      "default_popup": "popup.html"
  },

  "permissions": [
    "tabGroups"
  ]



}

---------------------------------------


PROBLEM:-

When I use these 3 files, I get No errors - YAY!!!!

However, when I open the app,  on *ANY* URL, it says the same thing, It doesn't differentiate between URLS I want or the URLS I dont want.

All that is displayed on the screen are text, and a button(with text)

   <h1>Google Dev Docs</h1>
    <button>Group Tabs</button>


WHAT I WANT:- is a "See Spot Run" tutorial,

NO CSS - No HTML - No FONTS - No 1000's lines if code that is unexplained as to what it does

Yes.html  (No HTML code of any kind - Just this one line - no HTML coding of any kind)
---------------

YES YOUR SCRIPT WORKS
---------------  

No.html  (No HTML code of any kind - Just this one line)
---------------

No The URL is incorrect - Go to the correct URL.
---------------  


Is there a good tutorial with the bare minimum code to have yes.html if it matches http://*.domain.com/  or no.html on any other URL.

wOxxOm

unread,
Jan 14, 2023, 3:17:31 AM1/14/23
to Chromium Extensions, gordo...@gmail.com, stefa...@gmail.com
It's unclear what the goal is, but your code is almost fine.
  1. Add /* after the domain name to query all matching tabs e.g.  const tabs = await chrome.tabs.query({url: "*://*.domain.com/*"});
  2. Replace "window." in background.js with "self." or simply use "location.href".
  3. In this case your background.js is meaningless though because it'll print the url of the background script. You don't need the background script for this functionality.
You can debug your popup in devtools: right-click the popup, then click inspect, go to the Sources panel, find your script and set breakpoints. To re-run the popup press the hotkey to reload the page e.g. F5 or Ctrl-R.

wOxxOm

unread,
Jan 14, 2023, 3:18:53 AM1/14/23
to Chromium Extensions, wOxxOm, gordo...@gmail.com, stefa...@gmail.com
Ah, if you want to get the current tab's URL in the popup:

const [tab] = await chrome.tabs.query({active: true, currentWindow: true});
const {url} = tab;

gordo...@gmail.com

unread,
Jan 14, 2023, 4:01:38 PM1/14/23
to Chromium Extensions
YES - ive got it working, Not how i wanted it, but I have it working

I wanted it to work - display working.html, and on any other website, show notworking.html  

Ive now got it totally disabled on any other website, but when its on the correct URL, it displays the popup..

Now to add some useful functionality.

SCRIPTS

manifest.json
===================

{
  "manifest_version": 3,
  "name": "Ktest 3",
  "version": "1.0",

"host_permissions": [
  "https://*.mywebsite.com"
],

  "background": {
    "service_worker": "background.js"

  },

  "action": {
    "default_popup": "popup.html"
  },

 "permissions": [
     "declarativeContent"
]
}


background.js (no idea how this works, but its working)
----------------------------------


chrome.action.disable();

chrome.runtime.onInstalled.addListener(() => {
  chrome.declarativeContent.onPageChanged.removeRules(() => {
    chrome.declarativeContent.onPageChanged.addRules([{
      conditions: chrome.runtime.getManifest().host_permissions.map(h => {
        const [, sub, host] = h.match(/:\/\/(\*\.)?([^/]+)/);
        return new chrome.declarativeContent.PageStateMatcher({
          pageUrl: sub ? {hostSuffix: '.' + host} : {hostEquals: host},
        });
      }),
      actions: [new chrome.declarativeContent.ShowAction()],
    }]);
  });
});



popup.html
------------------------------


<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  </head>
  <body>

    <h1>KTEST 3</h1>
    <button>Button</button>
 <div id='K1'></div>

wOxxOm

unread,
Jan 14, 2023, 4:07:47 PM1/14/23
to Chromium Extensions, gordo...@gmail.com
To show notworking.html by default try replacing chrome.action.disable() with chrome.action.setPopup({popup: 'notworking.html'})

wOxxOm

unread,
Jan 14, 2023, 4:13:03 PM1/14/23
to Chromium Extensions, wOxxOm, gordo...@gmail.com
Oops, sorry, no, that won't work because declarativeContent doesn't have an action to specify working.html.
You can change the contents or redirect inside popup at its start:

const [tab] = await chrome.tabs.query({active: true, currentWindow: true});
if (!new URL(tab.url).hostname.endsWith('.mywebsite.com')) {
  location.href = 'notworking.html';
Reply all
Reply to author
Forward
0 new messages