3

I'm trying to integrate a switch toggle button into my Chrome extension (manifest version 3). Yet get an error.

The code basis for this is based on the following link: Chrome Extension set toggle switch state in all tabs

I get the following error message:

Uncaught TypeError: Cannot read property 'sync' of undefined at content.js:5

And yes, "storage" is set in the manifest.json and the extension was also reloaded and uninstalled as a test.

It seems that I generally cannot access chrome.storage there. Is it possibly because the content.js is injected? Or maybe do i need to use the message passing API for that purpose ?

popup.js

function setToggleState() {
    chrome.storage.sync.get('isExtensionActive', storage => {
        chrome.storage.sync.set({
            isExtensionActive: !storage.isExtensionActive,
        });
    });
}

document.addEventListener('DOMContentLoaded', function () {
    var toggleBtn = document.getElementById('toggle-btn');

    toggleBtn.addEventListener('click', function () {
        setToggleState();
        // here comes my code to set/toggle button text (on|off)
    });
})

inject.js

function injectScript(file_path, tag) {
    var node = document.getElementsByTagName(tag)[0];
    var script = document.createElement('script');
    script.setAttribute('type', 'text/javascript');
    script.setAttribute('src', file_path);
    node.appendChild(script);
}

injectScript(chrome.runtime.getURL('/components/content/content.js'), 'body');

content.js

chrome.storage.sync.get('isExtensionActive', storage => {
    toggleSomething(storage.isExtensionActive);
});

chrome.storage.onChanged.addListener(changes => {
    if (changes.isExtensionActive) {
        toggleSomething(changes.isExtensionActive.newValue);
    }
});

function toggleSomething(state) {
    console.log('new state:', state);
    document.body.className = "state_" + state;

    chrome.action.setBadgeText({
        text: (state ? 'off' : '')
    });
}

manifest.json

{
    "manifest_version": 3,
    "name": "example",
    "version": "0.0.1",
    "description": "example",
    "short_name": "example",
    "permissions": ["tabs", "activeTab", "declarativeContent", "storage", 
    "unlimitedStorage", "contextMenus", "alarms", "notifications"],
    "host_permissions": ["<all_urls>"],
    "content_scripts": [{
        "matches": ["https://example.com/*"],
        "css": ["/components/popup/popup.css", "/components/content/content.css"],
        "js": ["/components/popup/popup.js", "/components/content/inject.js"],
        "all_frames": true,
        "run_at": "document_end"
    }],
    "web_accessible_resources": [{
        "resources": ["/components/popup/popup.js", "/components/content/inject.js", 
"/components/content/content.css", "chrome-extension://EXAMPLE-ID/content.css", 
  "/components/content/content.js", "chrome-extension://EXAMPLE-ID/content.js"],
        "matches": ["<all_urls>"]
    }],
    "options_ui": {
        "page": "/components/options/options.html",
        "open_in_tab": false
    },
    "action": {
        "default_title": "example title",
        "default_popup": "/components/popup/popup.html",
        "default_icon": {
            "16": "icons/icon16.png",
            "19": "icons/icon19.png",
            "32": "icons/icon32.png",
            "48": "icons/icon48.png",
            "128": "icons/icon128.png"
        }
    }
}
Julian
  • 598
  • 8
  • 23
  • 2
    The script you're adding to the page is no longer a content script, it's just a page script, so it can't access `chrome.storage` API. A page script is only necessary to access JS variables and functions of the web page so you probably don't need it. If you do, then access the storage API in the content script and use messaging to pass results to the page script, [example](https://stackoverflow.com/a/19312198). – wOxxOm Mar 26 '21 at 11:10
  • 1
    A better solution would be to display your UI in an iframe, [example](https://stackoverflow.com/a/25100953), where you will be able to use all `chrome` API directly. – wOxxOm Mar 26 '21 at 11:12

1 Answers1

1

add the "storage" permission:

{
  ...
,
  "permissions": ["storage"]
}
  • I don't understand your answer... Maybe you missed this in the original post? `"permissions": ["tabs", "activeTab", "declarativeContent", "storage", "unlimitedStorage", "contextMenus", "alarms", "notifications"],` – Arvo Bowen Mar 04 '22 at 15:28