How to permit an extension to function at `about:blank`?

Per the undermentioned, Chrome can permit this on a per-extension (opt-in) basis. [1] Does Firefox permit this? If so, can a user also permit an extension to function at about:blank?


  1. stackoverflow.com/revisions/22794135/4 ↩︎

Chrome, Firefox, and Safari all support injecting content scripts in special cases where a sub-frame matches about:blank or has an opaque origin (serializes to “null”).

That said, let’s take a step back. What are you trying to do in your extension? What are you trying to control as a user?

1 Like

@dotproto, thanks. I understand you estimating that this is an example of the X/Y problem, but I really do just want to permit arbitrary enabled extensions to operate on contentless internal pages.

The reason is that I frequently want to create reproduction steps and marketing screenshots for an extension that I would usually have to use either example.com or a local .html file for. Neither option are suitable because the former doesn’t set color-scheme: light dark;:

…and the latter is significantly less convenient than just visiting about:blank, which already solely serves this purpose:

Thanks for the clarification. In that case the answer is both yes and no. It’s weird. And there are cross-browser inconsistency here.

Before I get into it, I’d recommend avoiding all of this and just having an extension open a custom page in response to a keyboard shortcut or a custom address bar keyword. Heck, I think you can even do what you want using a bookmark.

Bookmarklet

  1. In Firefox, open the Bookmark Manager
  2. Click the gear icon near the top of the window and select Add Bookmark.
  3. In the Name field, enter “Blank” or whatever you want to call this bookmark.
  4. Enter the following text in the URL field:
    data:text/html,<DOCTYPE html><style>html { color-scheme: light dark; }</style>
    
  5. In the Keyword field, enter “blank” or whatever keyword you want to use to invoke this bookmark.
  6. Save the bookmark.
  7. Open a new tab, type blank (or whatever keyword you used) in the address bar, and hit enter.

You should now see a blank page that matches your system’s preferred color scheme. You’ll also notice that the address bar contains the URL value we entered for the bookmark.

Content scripts

Okay, let’s get into the weirdness of content scripts.

Content scripts declared either in the manifest or using scripting.registerContentScripts cannot target about:blank when the user directly navigates to it using the address bar. They can, however, inject into sub-frames or child windows when a page they can inject into loads about:blank in one of those contexts.

For example, here’s an extension that uses a content script to make example.com open a new child window to about:blank. Note that the about:blank page has a red background.

manifest.json

{
  "name": "match about blank",
  "version": "1.0.0",
  "manifest_version": 3,
  "content_scripts": [{
    "matches": ["*://*.example.com/*"],
    "js": ["content.js"],
    "world": "MAIN",
    "match_origin_as_fallback": true
  }]
}

content.js

var url = new URL(window.location.href)
if (url.origin === "https://example.com") {
  window.open("about:blank");
} else {
  document.body.style.background = "red";
}

The key here is match_origin_as_fallback, which allows you content scripts to be injected into page contexts that don’t have a standard location. This includes data: URLs, blobs, null origins, and about:blank.

In some scenarios, you may also want to pair this with all_frames, as by default content scripts only inject into the top level frame.

While the match_about_blank property also exists, I’d generally recommend against using it as match_origin_as_fallback also matches about:blank as well as other origins you’d typically also want to match.

The approach described here works in Chrome and Firefox. For some reason Firefox requires that you also declare that the content script is injected into the main world. ¯\_(ツ)_/¯

1 Like

@dotproto, that’s perfect. I suppose that to someone more knowledgeable, everything asked to them just looks like an X/Y, for it is. Thank you.