Search code examples
javascriptgoogle-chrome-extensionbrowserfirefox-addonfirefox-addon-webextensions

How to open a deeplink without creating a new tab or window in a web extension


I have an anchor tag which when selected should open a link to an external application (Obsidian). Here's an example link: obsidian://action?param1=value&param2=value.

I expect that clicking on the anchor opens the external application without creating windows or tabs.

Current Browsers:

  • Firefox
  • Chrome

Current Permissions:

  • tabs
  • storage

I'm trying to avoid hosts_permissions if possible.

Several tried methods:

In the below examples, my usage of the "browser" namespace is equivalent to the chrome namespace.

  • selecting anchor href
    • this opens confirmation window inside popup which cuts off the confirmation since my popup is smaller in size
  • window.open()
    • This opens a new tab which closes when the open button on the prompt window is selected. If the prompt is closed, an empty tab remains
  • browser.scripting.executeScript
    • This requires the scripting permission which is fine, but opening a URL inside an injected script requires declared access to the tab URL (hosts_permissions in my case)
  • window.open(message.value, '_self') within content_script
    • This works perfectly, except it requires the content_script and I need to match all URLs. Since I want to avoid hosts_permissions, this is not suitable
  • browser.tabs.create()
    • Same behavior as window.open()

Maybe there is another way or something I didn't think of like being able to resize the prompt window?


Solution

  • After some more research I have found that browser.tabs.update() is perfect for my use-case! It calls the deep-link without opening a new tab or window and somehow avoids changing the tab URL. I assume the foreign protocol has something to do with this.

    In my extension setup, I am calling this directly in the popup from an anchor tag.

    Example:

    async function openDeeplink(deeplink) {
         const [activeTab] = await browser.tabs.query({active: true, currentWindow:true});
         browser.tabs.update(activeTab.id, { url: deeplink });
    }