How to get current tab URL using Manifest v3?

12,710 views
Skip to first unread message

Ivan White

unread,
Jun 15, 2021, 4:40:13 PM6/15/21
to Chromium Extensions
How do I get the URL of the current tab in the background service worker in MV3?

Here's what I have:

let currentURL;

chrome.action.onClicked.addListener(handleBrowserActionClicked);

chrome.commands.onCommand.addListener(function(command) {
  console.log("Command:", command);
  handleBrowserActionClicked();
});

function handleBrowserActionClicked() {
  togglePlugin();
}
function togglePlugin() {
  console.log("toggle plugin");
  chrome.tabs.query({ active: true, currentWindow: true }, function(tabs) {
    chrome.tabs.sendMessage(tabs[0].id, { greeting: "activateFeedback" });
  });
}

// Fires when the active tab in a window changes.
chrome.tabs.onActivated.addListener(function () {
    console.log("TAB CHANGED")
    //firstTimeRunning = true
    //feedbackActivated = false
    currentURL = getTab()
    .then(console.log("Current URL: " + currentURL))
})

// Fired when a tab is updated.
chrome.tabs.onUpdated.addListener(function () {
    console.log("TAB UPDATED")
    currentURL = getTab() // line 32
    .then(console.log("Current URL: " + currentURL))
})

async function getTab() {
  let queryOptions = { active: true, currentWindow: true };
  let [tab] = await chrome.tabs.query(chrome.tabs[0].url); // line 38
  return tab;
}


Right now the service worker is logging "Current URL: [object Promise]" instead of, for example, "https://www.google.com"

It is also giving an error in the console (see comments above for line numbers)

background.js:38 Uncaught (in promise) TypeError: Cannot read property 'url' of undefined
    at getTab (background.js:38)
    at background.js:32


I think it may be something to do with my limited knowledge of promises!

Please help.
Thank you in advance.

Simeon Vincent

unread,
Jun 15, 2021, 7:20:32 PM6/15/21
to Ivan White, Chromium Extensions
We have a snippet in the Tabs API docs that shows how to get the current tab. To make that example a little more concrete, here's a contrived example of what it might look like in use.

async function getCurrentTab() {
let queryOptions = { active: true, currentWindow: true };
let [tab] = await chrome.tabs.query(queryOptions);
return tab;
}

chrome.runtime.onInstalled.addListener(async () => {
console.log(await getCurrentTab());
});

Okay, now let's take a look at your code. There are a couple things that stick out with your code sample.

First, you defined getTab() as an async function, so the value it returns will be a Promise, but you're not using a .then() or awaiting the result of the promise. That's why when you log the value it returns you get "Current URL: [object Promise]".

Second, the construction of your getTab() function has two big problems.
  • Line 38 currently contains the statement chrome.tabs[0].url. Unfortunately this will not give you manything meaningful because chrome.tabs is an object and does not have 0th property to access. Since there is no property on that object called 0, the value you get back is undefined. The error message you included says exactly that: "Cannot read property 'url' of undefined".
  • chrome.tabs.query expects an object that defines the query you're executing, not URL string or other value. See this method's docs for additional details. 
Third, both action.onClicked and commands.onCommand pass a Tab instance into the listener. As such, we can update the first few event listeners and function definitions to take advantage of this.

chrome.action.onClicked.addListener(handleBrowserActionClicked);

chrome.commands.onCommand.addListener(function(command, tab) {
console.log("Command:", command);
handleBrowserActionClicked(tab);
});

function handleBrowserActionClicked(tab) {
togglePlugin(tab);
}

function togglePlugin(tab) {
console.log("toggle plugin");
chrome.tabs.sendMessage(tabs.id, { greeting: "activateFeedback" });
}

Cheers,

Simeon - @dotproto
Chrome Extensions DevRel


--
You received this message because you are subscribed to the Google Groups "Chromium Extensions" group.
To unsubscribe from this group and stop receiving emails from it, send an email to chromium-extens...@chromium.org.
To view this discussion on the web visit https://groups.google.com/a/chromium.org/d/msgid/chromium-extensions/4dafc635-db23-43ac-ac5e-12e38dde960cn%40chromium.org.

Ivan White

unread,
Jun 15, 2021, 7:36:02 PM6/15/21
to Chromium Extensions, Simeon Vincent, Chromium Extensions, Ivan White
Thank you very much! Greatly appreciated.

lev

unread,
Apr 29, 2022, 7:42:17 AM4/29/22
to Chromium Extensions, ivanwh...@gmail.com, Simeon Vincent, Chromium Extensions
Should I use currentWindow: true or lastFocusedWindow: true?
https://code-examples.net/en/q/1e34bf
this guy says that lastFocusedWindow is better

Dan Dixon

unread,
Mar 3, 2024, 4:14:59 PMMar 3
to Chromium Extensions, lev, ivanwh...@gmail.com, Simeon Vincent, Chromium Extensions
This was super helpful, Simeon Vincent, Thank you!

This let me figure out how to call  chrome.scripting.executeScript from a command.

Now I can explicitly play or pause a YouTube video (as YouTube, unfortunately, only includes a play/pause toggle keyboard shortcut).

Cheers!


chrome.action.onClicked.addListener(playit);
chrome.action.onClicked.addListener(pauseit);

chrome.commands.onCommand.addListener(function(command, tab) {
  console.log("Command:", command);

  if (command == "play_tab")
  {
    playit(tab)
  }

  if (command == "pause_tab")
  {
    pauseit(tab)
  }

});

function playit(tab) {
  chrome.scripting.executeScript({
    target: { tabId: tab.id },
    func : playVideo,
  })
  .then(() => console.log("Play Video"));
}

function pauseit(tab) {
  chrome.scripting.executeScript({
    target: { tabId: tab.id },
    func : pauseVideo,
  })
  .then(() => console.log("Pause Video"));
}

function pauseVideo() {
  document.querySelectorAll('.html5-main-video').forEach(vid => vid.pause());
}
function playVideo() {
  document.querySelectorAll('.html5-main-video').forEach(vid => vid.play());
}


Reply all
Reply to author
Forward
0 new messages