I work for a company that runs its own internal golinks server.
There is something powerful (and fun) about shorthand URLs you fully control. I can type go/gh
in my browser's address bar and jump right to GitHub. Or go/wiki
to go to our internal wiki. Or go/md
to get to a markdown scratchpad I use.
I started to wonder how involved it would be to set golinks up for my personal computer. There are plenty of self-hosted options, but I wanted something even simpler. Could I create a browser-only solution?
I found Personal go links by Ian Fisher. Props to Ian because the article is both a solid intro to golinks generally, and a neat survey of a few different personal use setups. Ian shares that his own system is built on a Flask server and Firefox extension. He floats the idea of a browser-only approach, but mentions it would require reloading the extension to update golinks, a poor UX.
Challenge accepted.
My criteria:
- A personal golinks system, entirely browser-based (via extension)
- Managing golinks should not require reloading the extension
- Support for Chromium-based browsers (I use Brave)
- All golink data should stay local
Browser extension APIs
Ian's browser extension uses the webRequest.onBeforeRequest
to intercept browser requests. If a request is made to go/gh
, and it matches a defined golink, the browser redirects (see section titled The code in the linked article)
(Un)fortunately, browser extension APIs are second only to AI in their rate of change. Chrome now throws warnings in new extensions when using onBeforeRequest
for redirects. Google now suggests using chrome.declarativeNetRequest
for redirection. More info on the differences between the two can be found here.
Redirects with declarativeNetRequest
While different, declarativeNetRequest
supports defining redirect rules like this:
{
id: 1,
priority: 1,
action: {
type: "redirect",
redirect: { url: "https://github.com" },
},
condition: {
urlFilter: `||go/gh|`,
resourceTypes: ["main_frame"],
},
}
With this redirect rule, Chrome will redirect requests for go/gh
to https://github.com.
Bringing it all together
Using this pattern, we can build a golinks system entirely in the browser:
- When the user creates a golink, we'll define a redirect rule similar to above.
- We'll store golink data in
chrome.storage.local
, private to the extension. - When the user adds/deletes/modifies a golink, we'll update storage and refresh the rules.
We'll also create two special redirects:
- Requests to
go/
with no path: redirect to the extension dashboard. - Requests to
go/*
when*
does not match any golink: redirect to the extension's create golink form, prefilling the name field.
And that's pretty much it. The novel code, if you can call it that, can be found here. The remaining code is largely UI and logic for CRUD operations against the golink data.
We now have a working, browser-based personal golinks system!
If you're interested in using the extension check out the repo. As of now, golinks must be installed as an "unpacked extension." This really just involves downloading/cloning the source code, then pointing Chrome at the extension's directory. I found it was much faster to iterate on the project by installing it unpacked, and then once I finished I didn't really have a reason to submit to the Chrome Web Store. Check out the README for step-by-step instructions on installing.
Bonus
If you read this far, thanks! Here are a few more unique golinks I've found useful:
go/comp | -> | https://mail.google.com/mail/u/0/#inbox?compose=new |
go/wx | -> | https://google.com/search?q=weather+MY_ZIP_CODE |
go/nas | -> | dashboard for my homelab Unraid host |
go/router | -> | my router's web interface |
go/mlb, go/nba, go/nfl | -> | sports scoreboards |