firefox: add handlers.json configuration#8741
firefox: add handlers.json configuration#8741kugland wants to merge 1 commit intonix-community:masterfrom
Conversation
|
@khaneliman Rebased from master and removed comprehensive assertions and tests, as asked. |
Adds support for configuring Firefox's handlers.json file to manage MIME type and URL scheme handlers declaratively (at `programs.firefox.profiles.<profile>.handlers`). Handlers control how Firefox opens files and protocols (e.g., PDF viewers, `mailto:` handlers).
There was a problem hiding this comment.
Pull request overview
Adds a new Home Manager submodule to generate Firefox handlers.json per profile, enabling declarative configuration of MIME type and URL scheme handlers under programs.firefox.profiles.<name>.handlers.
Changes:
- Introduces
programs.firefox.profiles.<name>.handlersoptions and writeshandlers.jsoninto the Firefox profile directory. - Adds a module test fixture validating the generated
handlers.json. - Adds a news entry announcing the new option.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
modules/programs/firefox/mkFirefoxModule.nix |
Wires the new profiles.<name>.handlers submodule into the Firefox module and installs handlers.json into each profile. |
modules/programs/firefox/profiles/handlers.nix |
Defines the handlers options schema and JSON generation for handlers.json. |
tests/modules/programs/firefox/common.nix |
Registers the new handlers test in the Firefox test suite. |
tests/modules/programs/firefox/profiles/handlers/default.nix |
Adds a module test configuring handlers and asserting the generated file content. |
tests/modules/programs/firefox/profiles/handlers/expected-handlers.json |
Golden file for the expected handlers.json output. |
modules/misc/news/2025/12/2025-12-10_04-15-59.nix |
Announces the new Firefox handlers option in the news system. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| path = lib.mkOption { | ||
| type = lib.types.nullOr lib.types.str; | ||
| default = null; | ||
| description = '' | ||
| Path to the executable to be used. | ||
|
|
||
| Only one of 'path' or 'uriTemplate' should be set. | ||
| ''; | ||
| }; | ||
|
|
||
| uriTemplate = lib.mkOption { | ||
| type = lib.types.nullOr lib.types.str; | ||
| default = null; | ||
| description = '' | ||
| URI for the application handler. | ||
|
|
||
| Only one of 'path' or 'uriTemplate' should be set. | ||
| ''; | ||
| }; |
There was a problem hiding this comment.
The handler submodule docs state that only one of path or uriTemplate should be set, but the option types currently allow setting both (or neither) without any validation. Add an assertion (or a custom type/apply) that enforces exactly one of these fields is non-null for each handler entry, so misconfigurations fail fast during evaluation instead of producing an invalid handlers.json.
| handlers = lib.mkOption { | ||
| type = lib.types.listOf ( | ||
| lib.types.submodule { | ||
| options = { | ||
| name = lib.mkOption { | ||
| type = lib.types.nullOr lib.types.str; | ||
| default = null; | ||
| description = '' | ||
| Display name of the handler. | ||
| ''; | ||
| }; | ||
|
|
||
| path = lib.mkOption { | ||
| type = lib.types.nullOr lib.types.str; | ||
| default = null; | ||
| description = '' | ||
| Path to the executable to be used. | ||
|
|
||
| Only one of 'path' or 'uriTemplate' should be set. | ||
| ''; | ||
| }; | ||
|
|
||
| uriTemplate = lib.mkOption { | ||
| type = lib.types.nullOr lib.types.str; | ||
| default = null; | ||
| description = '' | ||
| URI for the application handler. | ||
|
|
||
| Only one of 'path' or 'uriTemplate' should be set. | ||
| ''; | ||
| }; | ||
| }; | ||
| } | ||
| ); | ||
| default = [ ]; | ||
| description = '' | ||
| An array of handlers with the first one being the default. | ||
| If you don't want to have a default handler, use an empty object for the first handler. | ||
| Only valid when action is set to 2 (Use helper app). | ||
| ''; | ||
| }; |
There was a problem hiding this comment.
handlers is documented as “Only valid when action is set to 2”, but nothing prevents users from setting handlers when action != 2 (or setting action = 2 with an empty handlers list), which can yield a handlers.json that Firefox may ignore or handle unexpectedly. Consider adding assertions tying these options together (e.g., require handlers == [] unless action == 2).
| type = lib.types.bool; | ||
| default = false; | ||
| description = '' | ||
| Whether to force replace the existing handlers configuration. |
There was a problem hiding this comment.
The force option description is very minimal compared to similar Firefox profile file options (e.g., profiles.<name>.search.force) that explain why force is commonly needed (Firefox overwriting/replacing files). Expanding this description would help users avoid configurations that work only until Firefox writes its own handlers.json.
| Whether to force replace the existing handlers configuration. | |
| Whether to forcefully replace the existing ``handlers.json`` in the Firefox profile | |
| with the configuration generated by this module. | |
| Firefox may create or update ``handlers.json`` at runtime as you change download and | |
| content-handling preferences. If this file is not managed by Nix, those changes can | |
| diverge from or overwrite the configuration declared here. | |
| When this option is set to ``true``, the Nix-managed ``handlers.json`` will be written | |
| even if a file already exists in the profile, ensuring that the declarative | |
| configuration defined by ``mimeTypes`` (and related options) consistently takes | |
| precedence over Firefox’s own modifications. | |
| Leave this at the default ``false`` if you prefer Firefox to manage ``handlers.json`` | |
| itself and only want to initialize it once or avoid overwriting changes made via the | |
| Firefox UI. |
| package, | ||
| modulePath, | ||
| profilePath, |
There was a problem hiding this comment.
The handler module takes package, modulePath, and profilePath as arguments but doesn’t use them anywhere, which makes the interface noisier and can confuse future maintainers. Either drop these unused arguments or use them (e.g., for assertions / error messages showing the option path) to keep the module signature minimal and meaningful.
| package, | |
| modulePath, | |
| profilePath, |
Description
Adds support for configuring Firefox's handlers.json file to manage MIME type and URL scheme handlers declaratively (at
programs.firefox.profiles.<profile>.handlers). Handlers control how Firefox opens files and protocols (e.g., PDF viewers,mailto:handlers).Checklist
Change is backwards compatible.
Code formatted with
nix fmtornix-shell -p treefmt nixfmt deadnix keep-sorted nixf-diagnose --run treefmt.Code tested through
nix run .#tests -- test-allornix-shell --pure tests -A run.all.Test cases updated/added. See example.
Commit messages are formatted like
See CONTRIBUTING for more information and recent commit messages for examples.
If this PR adds a new module
If this PR adds an exciting new feature or contains a breaking change.