3

With manifest v2 it is working fine. But with manifest v3 I'm getting error "ReferenceError: localStorage is not defined"

manifest.json

{
  "name": "Getting Started Example",
  "description": "Build an Extension!",
  "version": "1.0",
  "manifest_version": 3,
  "background": {
    "service_worker": "background.js"
  },
  "permissions": ["storage", "activeTab", "contextMenus"],
  "action": {
    "default_popup": "popup.html"
  }
}

background.js

var contextMenuItems = {
  "title": 'Add to notepad"',
  "contexts": ["selection"],
  "id": "myContextMenuId"
};
chrome.contextMenus.create(contextMenuItems);
chrome.contextMenus.onClicked.addListener(function(clickData){
  if(clickData.menuItemId == "myContextMenuId" && clickData.selectionText){
   localStorage.setItem("text", "clickData.selectionText");
  }
});
DeeKay
  • 33
  • 6

2 Answers2

7

The background script in ManifestV3 is a service worker now so it can't access stuff exposed only on window like HTML5 localStorage or DOM. By the way, service workers don't have window, their global context is self or globalThis.

The solution is to switch to chrome.storage.local. It's an entirely different storage available in all extension contexts including content scripts. Note that a) it's asynchronous so the usage is different and b) it doesn't currently return a Promise due to a bug in Chrome so you can't await it. Until it's fixed, use the callback version shown in the documentation.

Storing:

chrome.contextMenus.onClicked.addListener(info => {
  if (info.menuItemId == 'myContextMenuId' && info.selectionText) {
    chrome.storage.local.set({text: info.selectionText});
  }
});

Reading in popup:

chrome.storage.local.get('text', ({text}) => {
  // the callback runs asynchronously so you should use the value here
  document.body.prepend(text);
});
wOxxOm
  • 65,848
  • 11
  • 132
  • 136
1

For Typescript users or if you want to support firefox also then you can use a plugin called as webextension-polyfill ,and it is promises based

Code

 import browser from "webextension-polyfill";

 browser.storage.local.get(['text']).then((res)=>{
 console.log(res)
});

Goutham J.M
  • 1,726
  • 12
  • 25