0

I have this code in my chrome extension backround.js file

const bannedHosts = [];

const setupContextMenus = () => {
    chrome.contextMenus.create({
        id: 'blockHost',
        type: 'normal',
        contexts: ['all'],
        title: 'Block website',
    })

    chrome.contextMenus.create({
        id: 'unblockHost',
        type: 'normal',
        contexts: ['all'],
        title: 'Unblock website',
    })
}


chrome.runtime.onInstalled.addListener( () => {
    console.log('extension installed')
    setupContextMenus()
})

chrome.contextMenus.onClicked.addListener( ( clickData) => {
    if( clickData.menuItemId === 'blockHost' ) {
        console.log(clickData)
        bannedHosts.push(clickData.pageUrl)
        
        chrome.declarativeNetRequest.updateDynamicRules({
            removeRuleIds: bannedHosts.map((h, i) => i + 1),
            addRules: bannedHosts.map((h, i) => ({
                id: i + 1,
                action: {type: 'redirect', redirect: {extensionPath: '/options.html'}},
                condition: {urlFilter: `||${h}/`, resourceTypes: ['main_frame', 'sub_frame']},
            }))
        });
        console.log(bannedHosts)
    } else if( clickData.menuItemId === 'unblockHost' ) {
      ...
    }
})

I'm doing a quick test of the code by installing the extension, I'm able to see the context menu voices and I'm able to track the click event. My problem is with the declarativeNerRequest, I've noticed that when an url is added to the array blockedHosts, the rule that I want to add that is supposed to redirect the user to the options page will not work and if I try to visit the website it will be displayed instead of redirecting the user.

I have declared the correct permission in manifest v3, how I can fix this problem? How I add correctly a new url and a rule to block it and how I can remove the related url and rule if needed?

manifest file

import { defineManifest } from '@crxjs/vite-plugin'

export default defineManifest({
  name: '',
  description: '',
  version: '1.0.0',
  manifest_version: 3,
  icons: {
    16: 'img/logo-16.png',
    32: 'img/logo-34.png',
    48: 'img/logo-48.png',
    128: 'img/logo-128.png',
  },
  action: {
    // default_popup: 'popup.html',
    // default_icon: 'img/logo-48.png',
  },
  options_page: 'options.html',
  background: {
    service_worker: 'src/background/index.js',
    type: 'module',
  },
  content_scripts: [
    {
      matches: ['http://*/*', 'https://*/*'],
      js: ['src/content/index.js'],
    },
  ],
  host_permissions: [
    '<all_urls>'
  ],
  web_accessible_resources: [
    {
      resources: [
        'img/logo-16.png', 
        'img/logo-34.png', 
        'img/logo-48.png', 
        'img/logo-128.png',
        'options.html'
      ],
      matches: [
        '<all_urls>'
      ],
    },
  ],
  permissions: [
    'tabs',
    'contextMenus',
    'webRequest',
    'webRequestBlocking',
    'declarativeNetRequest'
  ]
})
newbiedev
  • 2,607
  • 3
  • 17
  • 65
  • 1) Declare options.html in [web_accessible_resources](https://developer.chrome.com/docs/extensions/mv3/manifest/web_accessible_resources/). 2) Add `""` in "host_permissions" in manifest.json or use [optional_host_permissions](https://developer.chrome.com/docs/extensions/reference/permissions/). – wOxxOm Aug 12 '22 at 17:52
  • I already have the `host_permissions` set on ``, maybe I need to add the options page to the web accessible resources where at the moment I didn't set nothing – newbiedev Aug 12 '22 at 18:13
  • @wOxxOm I've tried to rebuild the extension but there is no way to make it working – newbiedev Aug 14 '22 at 15:34
  • clickData.pageUrl is not a host, it's a URL. Use `new URL(clickData.pageUrl).hostname` or change `urlFilter` if you want to block the exact page. – wOxxOm Aug 14 '22 at 18:15
  • @wOxxOm ok, I will test your suggestion. I want to block the whole site not the single url. – newbiedev Aug 15 '22 at 12:45
  • @wOxxOm now that I've used the ´new URL()´ function to extract the hostname the new added sites are blocked correctly and the page I want to display is loaded. The problem is to remove the host, is there any way? – newbiedev Aug 15 '22 at 15:28
  • Use chrome.declarativeNetRequest.getDynamicRules, find the entry for the host in its result, then use chrome.declarativeNetRequest.updateDynamicRules with that rule's id in removeRuleIds parameter. – wOxxOm Aug 15 '22 at 17:37

0 Answers0