For Home Manager 26.11 (unstable as now)

Thanks to https://github.com/nix-community/home-manager/pull/9898, manifestUrl is now optional. Omit it for non-PWA websites. 😄

The rationale of the implementation is based on https://github.com/nix-community/home-manager/issues/9818 and on this article!

For Home Manager 26.05 and older

Tip

TL;DR: use data:application/manifest+json;base64,e30= as manifest URL and configure the PWA through programs.firefoxpwa.profiles.<name>.sites.<name>.settings. Rationale below. 😄

Introduction

PWAsForFirefox, also known as FirefoxPWA, added support for non-PWA websites in v0.4.012 to give users the flexibility to install any website as a PWA. The same mechanism covers PWAs with invalid manifests (permalink): unticking “Use manifest” makes the extension generate a fake one instead.

I started using programs.firefoxpwa with standard PWAs. Then I wanted to install LinkedIn as a PWA.

LinkedIn, however, doesn’t have a PWA.

How support for non-PWA websites works

When a non-PWA website is installed, the extension:

  1. Generates a “fake” manifest with four fields:
    • start_url
    • name
    • description
    • icons
  2. Encodes the JSON as base64.
  3. Creates a data URL: data:application/manifest+json;base64,<GENERATED_MANIFEST_JSON_BASE64>.
  4. Uses the created data: URL as the manifest URL.

So the non-PWA website now has a PWA manifest.

Configure a non-PWA website using the Home Manager options

Normally, we would set programs.firefoxpwa.profiles.<name>.sites.<name>.manifestUrl to the manifest’s URL. However, non-PWA websites don’t have a manifest, and the module doesn’t document what to use instead.

We just saw how PWAsForFirefox builds a manifest, but Home Manager takes a different path: it writes the config file itself, so none of those four fields are read3.

Tip

Although the manifest values are ignored, you can configure the PWA through programs.firefoxpwa.profiles.<name>.sites.<name>.settings.

For example, to set an icon for your PWA, you can use:

1
settings.config.icon_url = "https://www.linkedin.com/favicon.ico";

This also applies to valid PWAs.

Since the manifest is ignored, we can use a data URL containing an empty JSON object encoded in base64. 😄

1
2
$ echo -n '{}' | base64
e30=

So the resulting URL is:

data:application/manifest+json;base64,e30=

Now set that as your manifestUrl:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
{
  programs.firefoxpwa = {
    enable = true;
    profiles = {
      "XXXXXXXXXXXXXXXXXXXXXXXXXX".sites."YYYYYYYYYYYYYYYYYYYYYYYYYY" = {
        name = "LinkedIn";
        url = "https://www.linkedin.com/";
        manifestUrl = "data:application/manifest+json;base64,e30="; # <-- Our generated "manifest" URL.
      };
    };
  };
}
Tip

XXX… and YYY… are ULIDs identifying the profile and the website.

You can generate them with any ULID generator, for example https://ulidgenerator.com/.

Rebuild and enjoy your non-PWA website installed as a PWA! 😄