Posts   |   About

Fixing Content Scripts on

When writing a WebExtension using content scripts on, you’ll quickly find they don’t work as expected: the content scripts won’t run when clicking links, e.g. when clicking into an issue from the issues list.

Content scripts ordinarily reload for each new page visited but, on GitHub, they don’t. This is because links on GitHub mutate the DOM and use the history.pushState API instead of loading pages the standard way, which would create an entirely new DOM per page.

I wrote a content script to fix this, which you can easily drop into your own WebExtensions. The script works by adding a MutationObserver that will check when the DOM has been updated, thus indicating that the new page has been loaded from a user’s perspective, and notify the WebExtension about this event.

If you want to try it out, the source is on GitHub. You can also check out a sample.


The seemingly “correct” approach would be to create a history.pushState observer using the webNavigation.onHistoryStateUpdated listener. However, this listener does not work as expected: it’s called twice – once before the DOM has been mutated and once after – and I haven’t found a good way to distinguish them other than to look at changes in the DOM, which is already the approach my solution takes.

This post is written by Michael Comella, a developer at Mozilla currently working on Firefox performance.
This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.
Creative Commons License