google docs sidebar dev log: day 1 & 2
I’ve been building my first Chrome extension, a little sidebar menu on Google Docs that lists your other recently-viewed docs.
I’m trying something new where I document my progress, learnings, and milestones on each project as I build. This is a suggestion from my friend Jonnie, who wisely noted that the most valuable outcome of a project is often not the work itself, but the journal entries along the way. It’s a way to celebrate the process rather than the outcome. Plus, the writing and documenting can serve as a welcome break from designing and coding.
I used to want to do all this how-I-built-this documentation after finishing the project, but as I learned from building TRASH BABY, I’m usually so exhausted by trying to get a project over the finish line that I have no more energy to think or write or talk about it, and I’ve forgotten the most interesting details in the slog of building. These are mostly meant for myself and my memories, but may also be helpful to others who want to build similar projects or see how I work.
I’m looking forward to keeping this up. I expect to only have 1-2 days a week to work on this project while I balance it with client work. I can write my recaps and record my vlogs on non-coding days. (I’ve also learned that trying to write/vlog in the same day as building is too much for my brain to handle.) I’m writing this on a flight without wifi, so this is more verbose and thorough than usual. Future devlogs will probably be just cover one day at a time and be much shorter.
Why build this?
I like to build products that I myself would use. While working a corporate job, I found myself drowning in scattered Google Docs and Sheets, always having a hundred tabs open but never being able to find what I was looking for. I never had the energy to properly organize it in Google Drive — come on, that’s a whole different website that I don’t have the brainspace to look at! All I needed was a simple sidebar list, like in Notion or Apple Notes.
A sidebar menu seemed like a viable Chrome extension project. I was looking forward to getting back into the faster, more familiar world of web dev after working in React Native so much last year. I didn’t want to deal with a bunch of backend stuff either — I learned I have little interest in coding things that aren’t visible to the end user. Plus, I’d become more curious about Chrome extensions in general as a way to deploy AI agents, so it was a good opportunity to familiarize myself with the how they work.
Design log
I had some energy over the holidays, so I started sketching out what I wanted to exist. It was a fairly obvious design in my head, but I learned from TRASH BABY that having a dedicated design phase and tight spec helps me build it faster. Leaving too much open-ended before I start coding is a recipe for endless spinning.
Thu, Dec 28, 2023
Spent ~an hour sketching a sidebar in Figma. They mostly look like some variation of a persistent sidebar:
Mon, Jan 1, 2024
Cleaned it up into a simple Figma prototype — rounded out some rough edges like animations. I’m glad I did, because it helped me decide I wanted a show-on-hover interaction rather than a persistently-visible sidebar.
I wasn’t sure when I would have the time to build this, so I posted a Tiktok testing the waters.
Dev log day 1
Tue, Jan 2
I was expecting to work on client work today, but turns out I had a bonus day off. Perfect opportunity to get started with uninterrupted focus.
I noticed a cool milestone: almost a year ago to the day, I started coding again using ChatGPT as a coding tutor. I was still intimidated by programming. Now I look forward to the days when I have uninterrupted time to build stuff I don’t know how to build. :)
EOD goal: I wasn’t sure how to milestone this since I hadn’t built a Chrome extension before. Ideally, I could get a list of my Google Docs to show up in the sidebar by EOD — felt ambitious, but I knew hitting this milestone on Day 1 would make me really motivated to continue.
Spoiler alert, I hit this milestone!
I’m getting pretty good at milestoning/cutting scope in a way that keeps my own excitement and momentum going. I hope to keep it up.
I started, as always, by asking ChatGPT how to build it. It doesn’t give me all the answers and is wrong quite often, but it makes thinking through the problem so much easier.
I ended up restarting my implementation 3 times. This is more complicated than I expected. I am so bad at this.
First, I put together the extension files (
manifest.json
,content-script.js
) in a blank project. Vanilla HTML, CSS, JS.I got a skeleton of a static sidebar showing up on Google Docs.
It turns out you always have to refresh your unpacked extension while developing, in order to see the changes in your browser. Not painful, but adds friction and room for error.
When I went to hook it up to the Google Drive API, I realized I didn’t know how to make dynamic web apps without React. And I wanted to think about components and state management in React-y ways.
Then, I tried rebuilding it with an open-source template I found via Reddit, create-react-chrome-extension
Not fun. I didn’t understand enough of what was going on to understand what was template code I could replace vs. what I had to keep.
The functionality I needed for my extension required a lot of modifying the content script. But the React part of this template seemed to only apply to the
popup.js
. Ultimately, this template didn’t seem to use React in the right part of the Chrome extension for me.
So I rebuilt it again with another open-source template, react-content-script, that compiles React code into a static
content-script.js
This template was a lot more readable, with obvious example code so I knew what I could delete
This one already uses Typescript, yay.
I decided to use Tailwind for convenience. I know Tailwind gets a lot of flack but it makes styling a starter React project so much easier. Found a pull request adding Tailwind to the popup.js; I extended the Tailwind to also work for the content script.
All the other versions I tried weren’t wastes of time — I was able to copy over a lot of my code from the previous versions of the projects.
Upgraded
react-content-script
’smanifest.json
from V2 to V3This project used Vite to build the React code to static files that can be served via JS extension. I had heard of it but hadn’t used it before.
Spent an unreasonable amount of time (like, 30m-1h) trying to get Vite to auto-compile upon file change, only to realize after giving up that this template already does that and all my changes were breaking it. Oops.
Hooked it up to Google Drive API. Got a sidebar working with a list of my own docs! Hit the milestone! Feels fucking great! I am so good at this and nobody can tell me otherwise.
Learned that the content scripts can’t make cross-origin requests for security reasons. Instead, you have to pass messages back and forth with the
background.js
service worker.Just reading out-of-the-box docs and getting-started guides weren’t the most helpful for me since Chrome Extension docs assume something simple, and the Google Drive API docs assume a standalone app. But at least I could make a standard
fetch
request frombackground.js
.The Drive API limit is 500k API requests a day. It’s a big number, but I could see a couple of power users at doc-heavy companies eating that up quickly, especially if I introduce Drive folder organization or search. But whatever, I’m going the inefficient prototypey route and making a new API request every time you hover to open the sidebar.
Off the high of hitting my milestone, I quickly polished up the sidebar visuals to match my mockup.
Added icons (home/refresh/plus)
Some time spinning on how to render SVG icons using Vite/SVGR. Ended up just making components for them since I don’t think I was able to get whatever SVGR is supposed to do, to work.
Got the menu showing/hiding on hover. (For the sake of easy dev, I had kept the menu persistently open while working on the sidebar contents.)
Finally made my first commit on this project lol, after a full day of work.
In between Day 1 and Day 2, I posted updates to Tiktok and Twitter just to celebrate this milestone and to gauge more interest.
Dev log day 2
Mon, Jan 8
EOD goal: submit to Chrome Web Store. Wanted to see if I could finish an MVP today.
Added support to also show the sidebar on Google Forms, Sheets, and Slides.
Sidebar lists your recent files of the same filetype, i.e. if you are looking at a google sheet, the sidebar lists other recent sheets.
Interesting: Forms has a noticeably different implementation than Sheets/Slides.
Spent probably 30min trying to get too clever/neat about my constants, and made some bad abstractions that led to some ridiculous ChatGPT suggestions like this:
onClick={() => window.open(NEW_FILE_URL[product as keyof typeof NEW_FILE_URL], "_blank”)}
Anyway, wrote some ugly but clear code to account for the differences in products
I did end up submitting to the extension just to hit the milestone and feel like I made progress. And also to make sure there were no issues with the review process that could throw off my timeline and energy. (I learned the hard way with Apple’s App Review.)
Added privacy policy (forking one I found on Github)
Added screenshot, description, support email, listing why I’m requesting permissions, etc.
But I cut a lot of corners or ignored a lot of major issues in order to just get through the submission process. This isn’t an MVP, not even ready for public beta yet.
Only people on my domain — not any Google account — can connect to their Google Drive. So, basically this app exists on the Chrome Web Store but only I can use it.
I need to go through a separate verification process to let people outside my domain connect to their Drives; part of that verification process includes having a live app URL.
The extension doesn’t support account switching yet — the sidebar always shows Google Drive info of the account that you’re logged in to Chrome with.
Notably, these are NOT related to the Google accounts that you can switch between on Google Docs. It’s very confusing.
Spent a lot of time reading up how to get around this. The internet tells me to build my own OAuth flow, or something. Sounds scary but I guess I have to figure it out at some point.
Some sort of closed-port bug I don’t understand. I might need to force some sort of reconnect after a timeout.
I ignored any local caching of the file list — the API requests remain incredibly inefficient.
Obviously, no future feature development until I solve these issues
Ignored issues with font (not sure how to access Google Sans), need to add credits/beta info/feedback submission form
Spent 30min trying to figure out if new version updates are automatically rolled out to users or not. I think they are. Wanted to check in case I introduced future breaking changes.
Overall: feeling daunted by the account switching & Google Drive API verification ahead. But not bad, I set a milestone and I hit it and I'm still excited about this project.