Farewell to bookmarklets

The Hypothesis web annotation system is a browser-based application that talks to an annotation server, finds annotations for the current page (if any), highlights the selections to which the annotations refer, and dispays them in a sidebar alongside the page. We load a fair bit of JavaScript to do our job, and in the olden days we would simply have relied on bookmarklets to activate that code.

But times change, and bookmarklets are mostly dead. They’re not all dead yet. I expect I’ll still be able to use simple ones, like pinboard.in‘s, for a long time to come. But a new security regime limits the scope of what bookmarklets can do, and is forcing developers to create browser extensions instead — extensions that must be created and deployed differently for each browser.

So the realm of web applications that extend the browser is now becoming as balkanized as the realm of mobile apps. Developers target the dominant platform first — currently, that’s Chrome — and then port their extensions to other browsers as and when they can.

There’s another way to add behavior to a web page, though. You can send the page through an intermediate server (a proxy) that injects that behavior as the bookmarklet or extension would do. The Hypothesis proxy is via.hypothes.is, and you can use it to activate annotation for any web page — including this one — like so:


The nice thing about this combo URL is that you can share the annotated page along with its annotation layer. Of course there are tradeoffs:

– Properly rewriting all the URLs in the proxied page is a tricky business.

– You can’t annotate pages behind paywalls (as you can with our bookmarklet and Chrome extension).

– You still need a way to activate the annotation layer for the current page. (You can use a bookmarklet to redirect to the proxy, but … sigh.)

The upshot is that we’re struggling to simplify the decision tree that Hypothesis users must traverse. You want to activate annotation for your current page? If in Chrome, install the extension, otherwise for Firefox or Safari or IE use the bookmarklet, unless the page enforces Content Security Policy, in which case use the proxy, unless the page is behind a paywall, in which case, sorry, you’re out of luck.

And that’s just for the desktop! Mobile browsers make things even crazier. I’m able to perform the gymnastics required to use the Hypothesis bookmarklet on my Windows Phone, on my iPhone, and (most acrobatically) on my Android tablet, and I really need to document those procedures, but it’s so depressing I’ve avoided doing so.

What seems most promising, for mobile browsers, is to add Hypothesis as an option that shows up when you ask to Share a web page. Activating annotation for the current page isn’t really Sharing, but the Share mechanism looks like the sanest way to redirect through the proxy, which in turn looks like the sanest way to activate the annotation layer in mobile browsers.

It looks reasonably straightforward to create an Android app that shows up when you Share a page and broadcasts the intent to view the proxied version of that page. Things look a bit more complex on iOS. Should there be a Safari-specific extension that redirects to the proxy? A system-wide Share extension that Chrome could also use? Both?

Of course activating Hypothesis on the mobile browser is only half the battle. As a sidebar-based app we manage pretty well on the desktop and large tablets, but are uncomfortable on smaller screens. If we’re routing through a proxy anyway, maybe the proxy should also do a Readability-style rewrite to simplify the page. We’re good at fuzzy anchoring and can anchor annotations to different representations of the “same” document.

There’s lots to do, and while bookmarklets will continue to help us do it, their era is over. Browsers are more standards-compliant than ever, which makes our mission to bring an annotation layer to the web easier than it would have been five or ten years ago. But browsers are now also less easily extensible and that’s a new challenge.

Posted in .

16 thoughts on “Farewell to bookmarklets

  1. “I wonder for how long.”

    Yeah. What I omitted from the above, I realize, is the always-on aspect of extensions which dates back to Greasemonkey, a tech that was and remains balkanized.

  2. I must be dense because after reading the bookmarklets are dead post several times I am not clear what one can and cannot do under the revised policy– the issues are when the js in the bookmarks script makes a call to a script hosted elsewhere??

    1. Our bookmarklet injects script. A site that refuses to allow that is GitHub:

      Refused to load the script ‘https://hypothes.is/app/embed.js’ because it violates the following Content Security Policy directive: “script-src assets-cdn.github.com collector-cdn.github.com”.

  3. > Properly rewriting all the URLs in the proxied page is a tricky business

    Using a scheme like `https://via.hypothes.is/blog.jonudell.net` makes “rewriting” necessary (and hard).

    SharedCopy used a subdomain scheme, e.g. `http://blog.jonudell.net.443.via.hypothes.is`, doing things this way requires no rewrite and “always works”. I’d recommend you do it this way.

    e.g. https://www.youtube.com/watch?v=b478A2o0uO4

    1. In this example you wouldn’t copy the page, just source it from its origin? In general, you’d use a canonicalization scheme to express any arbitrary URL as a domain name?

      1. I would copy the page source and serve “as-is” from our host `blog.jonudell.net.443.via.hypothes.is`

        Without rewriting, we can be robust against even javascript generated urls, paths embedded within stylesheets @imported by stylesheets, etc.

        As long as the final request is `/assets/hello.png`, it would hit our host and we can infer it to be `https://blog.jonudell.net/assets/hello.png`. At this point we can choose to 302, 301 or even proxy that too.

        For sharedcopy’s purpose, I didn’t bother about links to “other hosts” (e.g. ads.google.com) so the browser continue to contact those hosts directly unmolested. I think hypothes.is would be the same

      2. > In this example you wouldn’t copy the page, just source it from its origin?

        I copy the page to protect against future changes at the source, so my annotations and anchors hangs on a frozen copy. But the content of the page is unmodified as far as url rewrite is concern.

        > In general, you’d use a canonicalization scheme to express any arbitrary URL as a domain name?

        Yes, just the domain name and port. To think of it, I should’ve baked protocol and port into the scheme so I wouldn’t need to hardcode “443” as “https”.

  4. Hi Jon,

    You failed to mention another drawback of the proxy approach: Annotations are now tied to the proxied URL, which becomes a SPOF (or an attractive place to extract rents, depending on your business model).

    You need to add in federation of self hosted annotation servers to avoid this problem.

  5. I disabled CSP in my browser (Set security.csp.enable to false via about:config). My bookmarklets are more important to me than whatever CSP promises to deliver.

  6. I don’t agree with this. I use 16 bookmarklets on a daily basis for work. I’m not sure they’ll die just yet. You do need to be a bit careful about what you do with them as simply popping a new window isn’t allowed anymore. Instead you need to append a script to the current page, then handle it from that ;)

  7. Well, it’s now 2019 and I still use pretty complex bookmarklets.
    As I heavily rely on them I hope they’ll continue to live on.

Leave a Reply