javascriptgoogle-chrome-extensiongoogle-chrome-storage

How to get chrome storage to save on chrome extension popup close


I am trying to get this chrome storage sync set to run when the person closes the popup window in my chrome extension but cannot seem to get it working. That way if they abruptly close the extension window say by clicking in their browser or whatever their data still stores. Anyone have any ideas?


window.addEventListener("beforeunload", function load(unloadEvent) {
  let currentTimeGet = document.getElementById("currentTimeInfo").innerHTML;

  chrome.storage.sync.set({ ct: currentTimeGet }, function() {
    console.log("Value is set to " + currentTimeGet);
  });
});



Solution

  • The most reliable solution is to autosave on any change.

    This is the preferable and modern user-friendly solution. You can give the elements an id that's equal to their name in chrome.storage like <input type="text" id="userName" class="storage">.

    const STORAGE_SELECTOR = '.storage[id]';
    let debounceTimer;
    
    document.addEventListener('change', saveOnChange);
    document.addEventListener('input', saveOnChange);
    
    
    function saveOnChange(e) {
      if (e.target.closest(STORAGE_SELECTOR)) {
        clearTimeout(debounceTimer);
        debounceTimer = setTimeout(doSave, 100);
      }
    }
    
    function collectData() {
      const data = {};
      for (const el of document.querySelectorAll(STORAGE_SELECTOR))
        data[el.id] = el.type === 'checkbox' ? el.checked : el.value; 
      return data;
    }
    

    As for doSave() function, either simply overwrite the current options data in storage

    function doSave() {
      chrome.storage.sync.set(collectData());
    }
    

    or save under a separate autoSave and check it the next time the popup is shown:

    function doSave() {
      chrome.storage.sync.set({autoSave: collectData()});
    }
    
    function loadFromStorage() {
      chrome.storage.sync.get(data => {
        if (data.autoSave) data = data.autoSave;
        for (const [id, value] of Object.entries(data)) {
          const el = document.getElementById(id);
          if (el) el[el.type === 'checkbox' ? 'checked' : 'value'] = value;
        }
      });
    }
    
    loadFromStorage();
    

    P.S. In ManifestV2 it was possible to save the data in unload event directly in the backround script's JavaScript window object e.g. chrome.extension.getBackgroundPage().popupData = collectData(), but it's impossible in ManifestV3 as it uses a service worker on the separate process thread and even In ManifstV2 it was bad because it required a persistent background page (or a temporarily persistent page) and because Chrome moves away from unload events in general. The data may be easily lost on a crash of the extension process or of the browser itself, it might be lost if the browser was closed by the user.