Data Storage & Retrieval Troubles with Bookmark Decay
Tags: project, extension, devjournal
Published: 2023-08-02 13:38:16

---
title: Data Storage & Retrieval Troubles with Bookmark Decay
series: Bookmark Decay
published: true
date: 2023-06-21 14:12:05 UTC
tags: ["project", "extension", "devjournal"]
canonical_url: https://www.thehappycactus.dev/posts/2023-06-21-storage-troubles/
---

# The Journey So Far

I’m building a web app/Chrome extension pair that allows your bookmarks to “decay” (grow old and disappear) over time; the intention is to encourage you to actually read those tabs you have open as opposed to letting them linger until your browser crashes. Now that I’ve completed the MVP for the extension, it’s time to work on the web app!

# Current Progress

Once I’d completed the basics for the Bookmark Decay extension, I was ready to start the web app. My favorite part, hooray!

However, it turns out I’d made a foolish assumption - that the `chrome.storage` API was available to a web browser. I wasn’t going to be able to simply call `chrome.storage.local.get('my-bookmark-decay-key')` to grab my Bookmark Decay data! Hmm.

# What Happened

Once I setup the initial Bookmark Decay webapp with Vite, I began, naturally, by fetching my existing bookmarks. Unfortunately for me, since it turns out the Storage API is strictly for extensions I’d either have to:

1. Find a new way to store the data from the extension in a more website-accessible way
2. Find a way to retrieve the data I’m already storing via the extension

Since I’d already completed my extension work, I thought I’d go with #2 and see how I could grab the data from the extension itself.

# My failure to appropriately understand content scripts

Eugh, boy, I definitely went through some “I’m a genius no wait I’m an idiot” cycles on this one. And I definitely should’ve [taken own my advice](https://www.thehappycactus.dev/posts/2023-05-03-wrasslin/) on more that one occasion. When will I learn, y’all? I got pretty far down the content scripts rabbit hole before realizing it didn’t have the tools I needed.

[In the docs](https://developer.chrome.com/docs/extensions/mv3/getstarted/extensions-101/#extension-files) content scripts are described as executing in the context of the web page and having the ability to modify the DOM of the pages they’re injected into. That, in addition to having access to the Storage API, seemed to my untrained eye to be exactly what I was looking for.

It turns out that, unfortunately, I was incorrect. While there’s messaging built into content scripts, that messaging is intended to go _between extensions_, not _from extensions to website_. It sounds like content scripts are really best used for when you want to manipulate the DOM (say, insert data from the extension directly into the webpage), vs. strictly messaging.

I won’t bore you with the multitude of attempts I made here<sup id="fnref:1"><a href="#fn:1" role="doc-noteref">1</a></sup>, but suffice it to say that this is when I went back to the drawing board and started reading about my other options.

![Bart Simpson carrying a cake that has 'At Least You Tried' written on it](https://media.giphy.com/media/26ybwvTX4DTkwst6U/giphy.gif)

# The real solution: background scripts (or “extension service workers”)

Unlike content scripts, service workers’ primary role is to respond to events from the page. I think I initially discounted them because, in my mind, I wasn’t interested in responding to a browser-specific event (at least, I didn’t think so at the time). However one of the events service workers can listen for is `onMessageExternal` - fired when a message is sent from either another extension _or_ a website. This made service workers exactly what I needed.

Creating a service worker that listened for the `onMessageExternal` event and calling its associated `sendMessage` function in the webapp turned out to be the solution I needed. Whew/hooray!

# Next Steps

Now that I can successfully retrieve my saved bookmarks from the extension, I can _actually_ start building the Bookmark Decay webapp. Looking forward to it!

And finally: keep an eye out for a tutorial on retrieving data from an extension via a webpage - I’ve learned enough about messaging between the two that I can lay it out pretty clearly. 👍

* * *

1. I’ll do it here! I tried multiple combinations of `postMessage`, `sendMessage`, and simple event listeners for the `message` event to get this to work from a content script. While sending an initial message was more or less a breeze, capturing it successfully and returning data wasn’t something I could ever get working. A lot of errors about the port being closed, or the source no longer existing plagued my existence until I discovered extension service workers. [↩︎](#fnref:1)