Firefox extensions

Is there a place like the ‘External Extensions’ directory in Chromium but for FIrefox? Put those signed xpi in the browser/extensions directory along side with the firefox executable binary works, but It may require to rebuild the derivation everytime, which seems to be a huge waste to the disk-space.

I don’t know if there is such a directory but if there is not it should be possible to just symlink everything together instead of rebuilding.

The problem is that firefox searches the directory beside its ‘real path’, create a browser/extensions directory near the symlink didn’t work. I have to copy the binary, which seems not a good idea.

I don’t know if I explain it clearly, I’m not good at English :rofl:

Oh I realize that we have patched firefox to use the MOZ_SYSTEM_DIR env var, which should point to a directory that contains plugins and extensions. Maybe we can make its value configurable in the firefox wrapper?

Or just put them in ~/.mozilla/extensions, but have to get the application id. And need to find the file which can control the preference so that one don’t have to enable all the extensions manually every time the configuration changes.

Oh I see. If they resolve the symlink that isn’t possible.

You could symlink together the extensions in a nix store directory and then point MOZ_SYSTEM_DIR there. Writing to the home directory (~/.mozilla) isn’t possible.

Yes, but I prefer using home-manager for per application config.
So we can link the xpi file to ~/.mozilla/<Firefox-Application-ID>/<xpi-id>.xpi,

  • <Firefox-Application-ID> is stored in the application.ini in the unwrapped firefox derivation
  • <xpi-id> for each extension is stored in the manifest.json, which can be retreived by extract the xpi file,

Don’t know if there is an elegant way to get the two values.

We can also store the configurations in about:config in the home.nix, then generate a corresponding user.js, start firefox with --profile <path> option and then user.js is live in <path>

Using a /nix/store approach still makes it possible to use home-manager. home is inherently stateful and storing files there loses some of nix’s benefits. The biggest thing I can think of is that you cannot install two different versions of firefox with different addons at the same time. So if possible, I think a /nix/store approach should be preferred.

I put together a quick overlay with a daily job producing a tarball. Quite rough for now but it contains the add-ons I typically use:

  • cookie-autodelete
  • decentraleyes
  • greasemonkey
  • https-everywhere
  • link-cleaner
  • octotree
  • privacy-badger17
  • reddit-enhancement-suite
  • save-page-we
  • styl-us
  • ublock-origin

Not particularly pretty but I use it in Home Manager like so:

nixpkgs.overlays = [
  (import (builtins.fetchTarball "https://gitlab.com/rycee/nixpkgs-firefox-addons/-/jobs/artifacts/master/raw/overlay.tar.gz?job=nixpkgs-overlay"))
];

home.file.".mozilla" = {
  source = pkgs.buildEnv {
    name = "firefox-addons";
    paths = with pkgs.firefox-addons; [
      cookie-autodelete
      decentraleyes
      greasemonkey
      https-everywhere
      link-cleaner
      octotree
      privacy-badger17
      reddit-enhancement-suite
      save-page-we
      styl-us
      ublock-origin
    ];
  } + "/share/mozilla";
  recursive = true;
};
4 Likes

Put together a simple Home Manager module for this overlay. It basically just wraps the example I gave in my previous post to let you put something like

programs.firefox-addons = with pkgs.firefox-addons; [
  https-everywhere
  privacy-badger
];

in your HM configuration. Ultimately I’d hope to put it in the “official” firefox module but I’m not sure how to handle such 3rd party overlays in a sane manner. If anybody has ideas I’d be happy to listen.

1 Like

Lovely!

A couple of questions:

  • what’s the hash in extensionPath?
  • does this work with any AMO extension, or only ones listed somewhere in the overlay?

The hash is actually the unique Firefox application ID: Install.rdf - MozillaZine Knowledge Base

So since the application ID is hard coded it would currently only work with Firefox extensions but I guess in principle it should be possible to parametrize the application ID. Then could have, for example, a thunderbird-addons module.

Thanks! But just to be clear: it’s not just a pre-whitelisted set of extensions that can be installed, right? IIRC that’s how the first iteration of this worked.

Well, it is absolutely possible to create and install your own extension packages. The overlay contains a simple convenience function buildFirefoxXpiAddon that can be used to download and install an XPI file. The function isn’t exposed outside the overlay at the moment but this could be changed.

The extensions that are part of the daily updated overlay is basically the ones that I happen to use. Additional ones could easily be added by adding to the list of known addons. Either by making a pull request of simply sending me a list of URL slugs (e.g., the “styl-us” in the URL Stylus – Get this Extension for 🦊 Firefox (en-US)).

When installing a new XPI file you have to go into the Firefox add-ons settings to enable it, I don’t know if there is a way to bypass this easily and I think I prefer having this step remain manual anyway.

hear be a shell script “to handle Firefox 60+ extensions
Manage installation, upgrade and removal of system wide and user extensions”

perhaps? #… at least for me this reads easier than .hs =P
this could be utilised some how to output ( firefox + extensions ).

plain text of the link
#github.com/
PLAIN-TEXT-LINK: NicolasBernaerts/ubuntu-scripts/blob/master/mozilla/firefox-extension-manager

because apparently discourse edits links on my behalf :open_mouth::sweat::disappointed_relieved::cold_sweat::cry::sweat_smile::joy::rofl::robot::poop:

FTR this is a/the permanent link to the latest most updated version for humans :face_with_symbols_over_mouth:

The problem with that is that all methods of managing extensions that Firefox makes available which do not touch the profile directory are imperative instead of declarative, allowing only instructions to install or uninstall extensions from the profile directory.
I don’t believe there can be any NixOS solution less complicated than running Firefox in a way that shadows the extension directory (user namespace + bindmount?) - so we will probably have to use home-manager and just accept that one profile must correspond to one set of extensions.

I don’t believe there can be any NixOS solution less complicated than running Firefox over a FUSE layer that shadows the extension directory - so we will probably have to use home-manager and just accept that one profile must correspond to one set of extensions.

There might be some solution along the lines of running Firefox during nix-build to initialise the extension directory, then overwrite the profile’s extensions directory on start. (I do that with whole profile, which is a bit easier, but maybe partial profile overwrite also works fine with some care).

What about this mechanism: Deploying Firefox with extensions | Firefox for Enterprise Help

Maybe combined with Customizing Firefox Using AutoConfig | Firefox for Enterprise Help

Both of those will install extensions to a users directory, leaving them there when started with a Firefox version without extension or when they are removed from the configuration.

Right, didn’t consider that. Apparently it is possible to install and remove addons using the windows registry. Maybe that code could be re-used for our usecase with a small patch.

1 Like