Fonts: Difference between revisions

From NixOS Wiki
imported>Ngiger
pkgs/font name may differ
m Added some sample code for Nerd Fonts package installation
 
(43 intermediate revisions by 25 users not shown)
Line 1: Line 1:
NixOS handles fonts like it handles many different parts of the system: they are not in an environment unless explicitly marked to be part of it. This guide covers the installation, configuration and troubleshooting of fonts.
== Installing fonts on NixOS ==
== Installing fonts on NixOS ==


NixOS has many font packages available, and you can easily search for your favourites on the [https://search.nixos.org/packages NixOS packages site].  
NixOS has many font packages available, and you can easily search for your favourites on the [https://search.nixos.org/packages NixOS packages site].  


Despite looking like normal packages, simply adding these font packages to your <code>environment.systemPackages</code> won't make the fonts accessible to applications. To achieve that, put these packages in the <code>[https://search.nixos.org/options/?query=fonts.fonts fonts.fonts]</code> NixOS options list instead.
Despite looking like normal packages, simply adding these font packages to your <code>environment.systemPackages</code> won't make the fonts accessible to applications. To achieve that, put these packages in the <code>[https://search.nixos.org/options?channel=unstable&show=fonts.packages&from=0&size=50&sort=relevance&type=packages&query=fonts.packages fonts.packages]</code> NixOS options list instead.
 


For example:  
''For example:''


<syntaxhighlight lang="nix">
<syntaxhighlight lang="nix">
fonts.fonts = with pkgs; [
fonts.packages = with pkgs; [
   noto-fonts
   noto-fonts
   noto-fonts-cjk
   noto-fonts-cjk
Line 16: Line 17:
   fira-code
   fira-code
   fira-code-symbols
   fira-code-symbols
   mplus-outline-fonts
   mplus-outline-fonts.githubRelease
   dina-font
   dina-font
   proggyfonts
   proggyfonts
Line 23: Line 24:


Be aware that sometimes font names and packages name differ and there is no universal convention in NixOS. See [https://discourse.nixos.org/t/guidelines-on-packaging-fonts/7683/2 Guidelines for font packaging]
Be aware that sometimes font names and packages name differ and there is no universal convention in NixOS. See [https://discourse.nixos.org/t/guidelines-on-packaging-fonts/7683/2 Guidelines for font packaging]
=== Installing specific fonts from nerdfonts ===
 
The <code>nerdfonts</code> package, which contains all fonts from the [https://www.nerdfonts.com/ nerdfonts] repository is quite large and conrains a large number of fonts which take some time to install. If you only need a selection of fonts from the package, you can overwrite the font selection on Stable 20.09 like so:
=== Shorthands for fonts ===
* <code>fonts.enableDefaultPackages</code>: when set to <code>true</code>, causes some "basic" fonts to be installed for reasonable Unicode coverage. Set to <code>true</code> if you are unsure about what languages you might end up reading.
* <code>fonts.enableGhostscriptFonts</code>: affects the <code>ghostscript</code> package. Ghostscript packages some URW fonts for the standard PostScript typefaces. If <code>true</code>, these fonts will be visible to GUI applications. You could set it to <code>true</code> if you want these fonts, but <code>gyre-fonts</code> (part of <code>fonts.enableDefaultPackages</code>) might be higher-quality depending on your judgement.
 
=== Installing specific nerdfonts ===
 
Before Nixpkgs commit [https://github.com/NixOS/nixpkgs/commit/de4dbc58fdeb84694d47d6c3f7b9f04a57cc4231 de4dbc5] that provides individual Nerd Fonts packages under the name <code>nerd-fonts</code>, the <code>nerdfonts</code> package, which contains all fonts from the [https://www.nerdfonts.com/ nerdfonts] repository was quite large and contained a large number of fonts which took some time to install. If you only need a selection of fonts from the package, you can overwrite the font selection on Stable 20.09 like so:


<syntaxhighlight lang="nix">
<syntaxhighlight lang="nix">
fonts.fonts = with pkgs; [
fonts.packages = with pkgs; [
   (nerdfonts.override { fonts = [ "FiraCode" "DroidSansMono" ]; })
   (nerdfonts.override { fonts = [ "FiraCode" "DroidSansMono" ]; })
];
];
</syntaxhighlight>
</syntaxhighlight>


This will cause NixOS to download only the [https://github.com/ryanoasis/nerd-fonts/tree/master/patched-fonts/FiraCode Fira Code] and [https://github.com/ryanoasis/nerd-fonts/tree/master/patched-fonts/DroidSansMono Droid Sans Mono] fonts from [https://github.com/ryanoasis/nerd-fonts nerd-fonts] instead of the whole package.
This will cause NixOS to download only the [https://github.com/ryanoasis/nerd-fonts/tree/master/patched-fonts/FiraCode Fira Code] and [https://github.com/ryanoasis/nerd-fonts/tree/master/patched-fonts/DroidSansMono Droid Sans Mono] fonts from [https://github.com/ryanoasis/nerd-fonts nerd-fonts] instead of the whole package. The relevant names can be found by looking at the file name for your relevant font on the [https://github.com/ryanoasis/nerd-fonts/releases official release page] assets.
 
For configurations using later versions of Nixpkgs, individual Nerd Fonts packages can be installed like so:<syntaxhighlight lang="nix">
fonts.packages = with pkgs; [
  nerd-fonts.fira-code
  nerd-fonts.droid-sans-mono
];
</syntaxhighlight>
 
=== Let Fontconfig know the fonts within your Nix profile ===
Nix inserts its user profile path into <code>$XDG_DATA_DIRS</code>, which Fontconfig by default doesn't look in. This cause graphical applications like KDE Plasma not able to recognize the fonts installed via <code>nix-env</code> or <code>nix profile</code>.
 
To solve this, add the file <code>100-nix.conf</code> to your Fontconfig user configuration directory (usually <code>$XDG_CONFIG_HOME/fontconfig/conf.d</code>):
<syntaxhighlight lang="xml">
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "urn:fontconfig:fonts.dtd">
<fontconfig>
  <!-- NIX_PROFILE is the path to your Nix profile. See Nix Reference Manual for details. -->
  <dir>NIX_PROFILE/lib/X11/fonts</dir>
  <dir>NIX_PROFILE/share/fonts</dir>
</fontconfig>
</syntaxhighlight>
and run <code>fc-cache</code>.
 
Alternatively, [https://nix-community.github.io/home-manager/options.xhtml#opt-fonts.fontconfig.enable enable Fontconfig configuration] in your Home Manager configuration.


=== Imperative installation of user fonts ===
=== Imperative installation of user fonts ===
This is useful for quick font experiments.
This is useful for quick font experiments.


Example: Install <code>SourceCodePro-Regular</code>.
''Example'': Install <code>SourceCodePro-Regular</code>.
<syntaxhighlight lang="bash">font=$(nix-build --no-out-link '<nixpkgs>' -A source-code-pro)/share/fonts/opentype/SourceCodePro-Regular.otf
<syntaxhighlight lang="bash">font=$(nix-build --no-out-link '<nixpkgs>' -A source-code-pro)/share/fonts/opentype/SourceCodePro-Regular.otf
cp $font ~/.local/share/fonts
cp $font ~/.local/share/fonts
Line 45: Line 76:
</syntaxhighlight>
</syntaxhighlight>


== Configuring fonts ==
The nixos key [https://search.nixos.org/options?channel=unstable&from=0&size=50&sort=relevance&type=packages&query=fonts.fontconfig <code>fonts.fontconfig</code>] (click to see the full list!) handles the fontconfig options. Some options are nicely wrapped in nix; there's always <code>localConf</code> to go straight to the XML.


=== Set multiple fonts for different languages ===
=== Set multiple fonts for different languages ===
If you want to use other languages alongside English, you may want to set appropriate fonts for each language in your whole OS. For example, a Persian speaker might want to use the [https://rastikerdar.github.io/vazir-font/ Vazir] font for Persian texts and the [https://design.ubuntu.com/font/ Ubuntu] font for English texts. Just put these lines into your <code>configuration.nix</code>:
If you want to use other languages alongside English, you may want to set appropriate fonts for each language in your whole OS. For example, a Persian speaker might want to use the [https://rastikerdar.github.io/vazirmatn/ Vazirmatn] font for Persian texts, but [https://design.ubuntu.com/font/ Ubuntu] and Liberation Serif fonts for English texts. Just put these lines into your <code>configuration.nix</code>:


<syntaxhighlight lang="nix">
<syntaxhighlight lang="nix">
#----=[ Fonts ]=----#
#----=[ Fonts ]=----#
fonts = {
fonts = {
   enableDefaultFonts = true;
   enableDefaultPackages = true;
   fonts = with pkgs; [  
   packages = with pkgs; [  
     pkgs.ubuntu_font_family
     ubuntu_font_family
 
    liberation_ttf
     # Persian Fonts
     # Persian Font
     pkgs.vazir-fonts
     vazir-fonts
   ];
   ];


   fontconfig = {
   fontconfig = {
    penultimate.enable = false;
     defaultFonts = {
     defaultFonts = {
       serif = [ "Vazir" "Ubuntu" ];
       serif = [ "Liberation Serif" "Vazirmatn" ];
       sansSerif = [ "Vazir" "Ubuntu" ];
       sansSerif = [ "Ubuntu" "Vazirmatn" ];
       monospace = [ "Ubuntu" ];
       monospace = [ "Ubuntu Mono" ];
     };
     };
   };
   };
};
};
</syntaxhighlight>
</syntaxhighlight>
NB:
* This actually just sets the font fallback order so that fontconfig tries using the English font first, then falls back to another font if the character set is not covered. You ''usually'' want to write the English font ''before'' the other-language font, because the other-language font might cover Latin characters too, preventing the English font from showing up.
* <code>defaultFonts</code> translates to <code>&lt;prefer&gt;</code> in the actual fontconfig file. See https://github.com/NixOS/nixpkgs/blob/nixos-23.11/nixos/modules/config/fonts/fontconfig.nix for how NixOS does it, and the links below for how fontconfig interpret it.
* Vazirmatn is actually a "sans-serif" font; using it for <code>serif</code> is not a good visual match. You might need not one, but two (or if you count monospace, three!) font packages for a language.


=== Use custom font substitutions ===
=== Use custom font substitutions ===
Line 76: Line 114:
For example, Okular may show in the ''Document Properties'' dialog that it has substituted DejaVu Sans Mono (a sans-serif font) in place of "NewCenturySchlbk". <code>fc-match NewCenturySchlbk</code> would display similiar info.
For example, Okular may show in the ''Document Properties'' dialog that it has substituted DejaVu Sans Mono (a sans-serif font) in place of "NewCenturySchlbk". <code>fc-match NewCenturySchlbk</code> would display similiar info.


Adding this to your <code>/etc/nixos/configuration.nix</code> should prompt it to use the nicer serif *Schola* font instead:
Adding this to your <code>/etc/nixos/configuration.nix</code> should prompt it to use the more similar (and nicer) serif ''Schola'' font instead:


<syntaxhighlight lang="nix">
<syntaxhighlight lang="nix">
fonts = {
fonts = {
   fonts = with pkgs; [ gyre-fonts ];
   packages = with pkgs; [ gyre-fonts ];
   fontconfig = {
   fontconfig = {
     localConf = ''
     localConf = ''
Line 95: Line 133:
For more information and examples on the xml configuration language:
For more information and examples on the xml configuration language:


* https://linux.die.net/man/5/fonts-conf
* https://www.mankier.com/5/fonts-conf
* https://wiki.archlinux.org/index.php/Font_configuration
* https://wiki.archlinux.org/index.php/Font_configuration
* https://wiki.archlinux.org/index.php/Font_configuration/Examples
* https://wiki.archlinux.org/index.php/Font_configuration/Examples


For a list of suitable replacement fonts:
* https://wiki.archlinux.org/title/Metric-compatible_fonts


== Troubleshooting ==
== Troubleshooting ==
Line 107: Line 147:


<syntaxhighlight lang="console">
<syntaxhighlight lang="console">
$ cd /nix/var/nix/profiles/system/sw/share/X11-fonts
$ cd /nix/var/nix/profiles/system/sw/share/X11/fonts
$ fc-query DejaVuSans.ttf | grep '^\s\+family:' | cut -d'"' -f2
$ fc-query DejaVuSans.ttf | grep '^\s\+family:' | cut -d'"' -f2
</syntaxhighlight>
</syntaxhighlight>
Note that you may need to set <code>fonts.fontDir.enable = true;</code> for that X11/fonts directory to exist.


=== Adding personal fonts to <code>~/.fonts</code> doesn't work ===
=== Adding personal fonts to <code>~/.fonts</code> doesn't work ===
Line 116: Line 158:


The new preferred location is in <code>$XDG_DATA_HOME/fonts</code>, which for most users will resolve to <code>~/.local/share/fonts</code><ref>https://lists.freedesktop.org/archives/fontconfig/2014-July/005270.html</ref>
The new preferred location is in <code>$XDG_DATA_HOME/fonts</code>, which for most users will resolve to <code>~/.local/share/fonts</code><ref>https://lists.freedesktop.org/archives/fontconfig/2014-July/005270.html</ref>
=== Flatpak applications can't find system fonts ===
First, enable <code>fontDir</code> in your NixOS configuration:
<syntaxhighlight lang="nix">
fonts.fontDir.enable = true;
</syntaxhighlight>
==== Best Solution: Just copy necessary fonts to <code>$HOME/.local/share/fonts</code> ====
Create fonts directory <code>$HOME/.local/share/fonts</code> and copy system fonts with option <code>-L, --dereference</code>  .<syntaxhighlight lang="bash">
mkdir $HOME/.local/share/fonts && cp -L /run/current-system/sw/share/X11/fonts/* $HOME/.local/share/fonts/
</syntaxhighlight>Note: There is '''no need''' to grant flatpak applications access to <code>$HOME/.local/share/fonts</code>.
Instead, if you do that, some applications (for example, steam) won't work.<blockquote>Internals: How it works?
Flatpak applications run in sandboxes. When you start a flatpak application, flatpak builds a rootfs for it with bubblewrap.
With <code>findmnt --task {PID of flatpak app}</code> , you can explore the details of its rootfs.
By default, flatpak mounts <code>$HOME/.local/share/fonts</code> to <code>/run/host/user-fonts</code> in rootfs of an flatpak application.<syntaxhighlight lang="json">
{
  "target": "/run/host/user-fonts",
  "source": "/dev/disk/by-uuid/b2e1e6b5-738b-410b-b736-6d5c3dbbe31f[/home/username/.local/share/fonts]",
  "fstype": "ext4",
  "options": "ro,nosuid,nodev,relatime"
}
</syntaxhighlight>Then flatpak application can read fonts from that to display contents correctly.</blockquote>
==== Another Method: Create symlink to system fonts at  <code>$HOME/.local/share/fonts</code> ====
<blockquote>'''Note:''' this method doesn't work for some flatpak applications (for example, steam)!
Error: <syntaxhighlight lang="console">
$ flatpak run com.valvesoftware.Steam
bwrap: Can't make symlink at /home/username/.local/share/fonts: File exists
</syntaxhighlight></blockquote>Create a symlink in <code>XDG_DATA_HOME/fonts</code> pointing to <code>/run/current-system/sw/share/X11/fonts</code>, e. g.
<syntaxhighlight lang="bash">
mkdir $HOME/.local/share/fonts && ln -s /run/current-system/sw/share/X11/fonts ~/.local/share/fonts/
</syntaxhighlight>
Now you have two options.
===== Option 1: allow the Flatpaks to access the font folder and <code>/nix/store</code> =====
By using the Flatpak CLI or the Flatseal Flatpak make the following directory available to all Flatpaks <code>$HOME/.local/share/fonts</code> and <code>$HOME/.icons</code> the appropriate commands for this are:
<syntaxhighlight lang="bash">
flatpak --user override --filesystem=$HOME/.local/share/fonts:ro
flatpak --user override --filesystem=$HOME/.icons:ro
</syntaxhighlight>
And, because <code>~/.local/share/fonts</code> is linked to <code>/run/current-system/sw/share/X11/fonts</code>, which in turn is linked to content in <code>/nix/store</code>. You need to grant flatpak applications access to the <code>/nix/store</code> directory, so that they can load fonts correctly. You may need to reboot for this to fully take effect.
<syntaxhighlight lang="bash">
flatpak --user override --filesystem=/nix/store:ro
flatpak --user override --filesystem=/run/current-system/sw/share/X11/fonts:ro
</syntaxhighlight>
===== Option 2: allow the Flatpaks to access the WHOLE filesystem =====
Allow them access the WHOLE filesystem of yours: <code>All system files</code> in Flatseal or equivalently <code>filesystem=host</code> available to your application, the command for this is:
<syntaxhighlight lang="bash">
flatpak --user override --filesystem=host
</syntaxhighlight>
It is important to keep in mind that some flatpak apps may refuse to launch if given certain permissions, such as the Steam flatpak.
=== Using bindfs for font support ===
<syntaxhighlight lang="nix">
  system.fsPackages = [ pkgs.bindfs ];
  fileSystems = let
    mkRoSymBind = path: {
      device = path;
      fsType = "fuse.bindfs";
      options = [ "ro" "resolve-symlinks" "x-gvfs-hide" ];
    };
    aggregatedIcons = pkgs.buildEnv {
      name = "system-icons";
      paths = with pkgs; [
        #libsForQt5.breeze-qt5  # for plasma
        gnome.gnome-themes-extra
      ];
      pathsToLink = [ "/share/icons" ];
    };
    aggregatedFonts = pkgs.buildEnv {
      name = "system-fonts";
      paths = config.fonts.packages;
      pathsToLink = [ "/share/fonts" ];
    };
  in {
    "/usr/share/icons" = mkRoSymBind "${aggregatedIcons}/share/icons";
    "/usr/local/share/fonts" = mkRoSymBind "${aggregatedFonts}/share/fonts";
  };
  fonts = {
    fontDir.enable = true;
    packages = with pkgs; [
      noto-fonts
      noto-fonts-emoji
      noto-fonts-cjk
    ];
  };
</syntaxhighlight>
=== Noto Color Emoji doesn't render on Firefox ===
Enable <code>useEmbeddedBitmaps</code> in your NixOs configuration.
<syntaxhighlight lang="nix">
fonts.fontconfig.useEmbeddedBitmaps = true;
</syntaxhighlight>


<hr />
<hr />
[[Category:Configuration]]
[[Category:Configuration]]
[[Category:Desktop]]
[[Category:Fonts]]

Latest revision as of 16:20, 19 December 2024

NixOS handles fonts like it handles many different parts of the system: they are not in an environment unless explicitly marked to be part of it. This guide covers the installation, configuration and troubleshooting of fonts.

Installing fonts on NixOS

NixOS has many font packages available, and you can easily search for your favourites on the NixOS packages site.

Despite looking like normal packages, simply adding these font packages to your environment.systemPackages won't make the fonts accessible to applications. To achieve that, put these packages in the fonts.packages NixOS options list instead.

For example:

fonts.packages = with pkgs; [
  noto-fonts
  noto-fonts-cjk
  noto-fonts-emoji
  liberation_ttf
  fira-code
  fira-code-symbols
  mplus-outline-fonts.githubRelease
  dina-font
  proggyfonts
];

Be aware that sometimes font names and packages name differ and there is no universal convention in NixOS. See Guidelines for font packaging

Shorthands for fonts

  • fonts.enableDefaultPackages: when set to true, causes some "basic" fonts to be installed for reasonable Unicode coverage. Set to true if you are unsure about what languages you might end up reading.
  • fonts.enableGhostscriptFonts: affects the ghostscript package. Ghostscript packages some URW fonts for the standard PostScript typefaces. If true, these fonts will be visible to GUI applications. You could set it to true if you want these fonts, but gyre-fonts (part of fonts.enableDefaultPackages) might be higher-quality depending on your judgement.

Installing specific nerdfonts

Before Nixpkgs commit de4dbc5 that provides individual Nerd Fonts packages under the name nerd-fonts, the nerdfonts package, which contains all fonts from the nerdfonts repository was quite large and contained a large number of fonts which took some time to install. If you only need a selection of fonts from the package, you can overwrite the font selection on Stable 20.09 like so:

fonts.packages = with pkgs; [
  (nerdfonts.override { fonts = [ "FiraCode" "DroidSansMono" ]; })
];

This will cause NixOS to download only the Fira Code and Droid Sans Mono fonts from nerd-fonts instead of the whole package. The relevant names can be found by looking at the file name for your relevant font on the official release page assets.

For configurations using later versions of Nixpkgs, individual Nerd Fonts packages can be installed like so:

fonts.packages = with pkgs; [
  nerd-fonts.fira-code
  nerd-fonts.droid-sans-mono
];

Let Fontconfig know the fonts within your Nix profile

Nix inserts its user profile path into $XDG_DATA_DIRS, which Fontconfig by default doesn't look in. This cause graphical applications like KDE Plasma not able to recognize the fonts installed via nix-env or nix profile.

To solve this, add the file 100-nix.conf to your Fontconfig user configuration directory (usually $XDG_CONFIG_HOME/fontconfig/conf.d):

<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "urn:fontconfig:fonts.dtd">
<fontconfig>
  <!-- NIX_PROFILE is the path to your Nix profile. See Nix Reference Manual for details. -->
  <dir>NIX_PROFILE/lib/X11/fonts</dir>
  <dir>NIX_PROFILE/share/fonts</dir>
</fontconfig>

and run fc-cache.

Alternatively, enable Fontconfig configuration in your Home Manager configuration.

Imperative installation of user fonts

This is useful for quick font experiments.

Example: Install SourceCodePro-Regular.

font=$(nix-build --no-out-link '<nixpkgs>' -A source-code-pro)/share/fonts/opentype/SourceCodePro-Regular.otf
cp $font ~/.local/share/fonts
fc-cache
# Verify that the font has been installed
fc-list -v | grep -i source

Configuring fonts

The nixos key fonts.fontconfig (click to see the full list!) handles the fontconfig options. Some options are nicely wrapped in nix; there's always localConf to go straight to the XML.

Set multiple fonts for different languages

If you want to use other languages alongside English, you may want to set appropriate fonts for each language in your whole OS. For example, a Persian speaker might want to use the Vazirmatn font for Persian texts, but Ubuntu and Liberation Serif fonts for English texts. Just put these lines into your configuration.nix:

#----=[ Fonts ]=----#
fonts = {
  enableDefaultPackages = true;
  packages = with pkgs; [ 
    ubuntu_font_family
    liberation_ttf
    # Persian Font
    vazir-fonts
  ];

  fontconfig = {
    defaultFonts = {
      serif = [  "Liberation Serif" "Vazirmatn" ];
      sansSerif = [ "Ubuntu" "Vazirmatn" ];
      monospace = [ "Ubuntu Mono" ];
    };
  };
};

NB:

  • This actually just sets the font fallback order so that fontconfig tries using the English font first, then falls back to another font if the character set is not covered. You usually want to write the English font before the other-language font, because the other-language font might cover Latin characters too, preventing the English font from showing up.
  • defaultFonts translates to <prefer> in the actual fontconfig file. See https://github.com/NixOS/nixpkgs/blob/nixos-23.11/nixos/modules/config/fonts/fontconfig.nix for how NixOS does it, and the links below for how fontconfig interpret it.
  • Vazirmatn is actually a "sans-serif" font; using it for serif is not a good visual match. You might need not one, but two (or if you count monospace, three!) font packages for a language.

Use custom font substitutions

Sometimes, documents may appear to have bad kerning or hard-to-read letter spacing, due to a bad substitution. For example, Okular may show in the Document Properties dialog that it has substituted DejaVu Sans Mono (a sans-serif font) in place of "NewCenturySchlbk". fc-match NewCenturySchlbk would display similiar info.

Adding this to your /etc/nixos/configuration.nix should prompt it to use the more similar (and nicer) serif Schola font instead:

fonts = {
  packages = with pkgs; [ gyre-fonts ];
  fontconfig = {
    localConf = ''
      <!-- use a less horrible font substition for pdfs such as https://www.bkent.net/Doc/mdarchiv.pdf -->
      <match target="pattern">
        <test qual="any" name="family"><string>NewCenturySchlbk</string></test>
        <edit name="family" mode="assign" binding="same"><string>TeX Gyre Schola</string></edit>
      </match>
    '';
  };
};

For more information and examples on the xml configuration language:

For a list of suitable replacement fonts:

Troubleshooting

What font names can be used in fonts.fontconfig.defaultFonts.monospace?

Those that fontconfig will understand. This can be queried from a font file using fc-query.

$ cd /nix/var/nix/profiles/system/sw/share/X11/fonts
$ fc-query DejaVuSans.ttf | grep '^\s\+family:' | cut -d'"' -f2

Note that you may need to set fonts.fontDir.enable = true; for that X11/fonts directory to exist.

Adding personal fonts to ~/.fonts doesn't work

The ~/.fonts directory is being deprecated upstream[1]. It already doesn't work in NixOS.

The new preferred location is in $XDG_DATA_HOME/fonts, which for most users will resolve to ~/.local/share/fonts[2]

Flatpak applications can't find system fonts

First, enable fontDir in your NixOS configuration:

fonts.fontDir.enable = true;

Best Solution: Just copy necessary fonts to $HOME/.local/share/fonts

Create fonts directory $HOME/.local/share/fonts and copy system fonts with option -L, --dereference .

mkdir $HOME/.local/share/fonts && cp -L /run/current-system/sw/share/X11/fonts/* $HOME/.local/share/fonts/

Note: There is no need to grant flatpak applications access to $HOME/.local/share/fonts. Instead, if you do that, some applications (for example, steam) won't work.

Internals: How it works?

Flatpak applications run in sandboxes. When you start a flatpak application, flatpak builds a rootfs for it with bubblewrap.

With findmnt --task {PID of flatpak app} , you can explore the details of its rootfs.

By default, flatpak mounts $HOME/.local/share/fonts to /run/host/user-fonts in rootfs of an flatpak application.

{
  "target": "/run/host/user-fonts",
  "source": "/dev/disk/by-uuid/b2e1e6b5-738b-410b-b736-6d5c3dbbe31f[/home/username/.local/share/fonts]",
  "fstype": "ext4",
  "options": "ro,nosuid,nodev,relatime"
}

Then flatpak application can read fonts from that to display contents correctly.

Another Method: Create symlink to system fonts at $HOME/.local/share/fonts

Note: this method doesn't work for some flatpak applications (for example, steam)! Error:

$ flatpak run com.valvesoftware.Steam
bwrap: Can't make symlink at /home/username/.local/share/fonts: File exists

Create a symlink in XDG_DATA_HOME/fonts pointing to /run/current-system/sw/share/X11/fonts, e. g.

mkdir $HOME/.local/share/fonts && ln -s /run/current-system/sw/share/X11/fonts ~/.local/share/fonts/

Now you have two options.

Option 1: allow the Flatpaks to access the font folder and /nix/store

By using the Flatpak CLI or the Flatseal Flatpak make the following directory available to all Flatpaks $HOME/.local/share/fonts and $HOME/.icons the appropriate commands for this are:

flatpak --user override --filesystem=$HOME/.local/share/fonts:ro
flatpak --user override --filesystem=$HOME/.icons:ro

And, because ~/.local/share/fonts is linked to /run/current-system/sw/share/X11/fonts, which in turn is linked to content in /nix/store. You need to grant flatpak applications access to the /nix/store directory, so that they can load fonts correctly. You may need to reboot for this to fully take effect.

flatpak --user override --filesystem=/nix/store:ro
flatpak --user override --filesystem=/run/current-system/sw/share/X11/fonts:ro
Option 2: allow the Flatpaks to access the WHOLE filesystem

Allow them access the WHOLE filesystem of yours: All system files in Flatseal or equivalently filesystem=host available to your application, the command for this is:

flatpak --user override --filesystem=host

It is important to keep in mind that some flatpak apps may refuse to launch if given certain permissions, such as the Steam flatpak.

Using bindfs for font support

  system.fsPackages = [ pkgs.bindfs ];
  fileSystems = let
    mkRoSymBind = path: {
      device = path;
      fsType = "fuse.bindfs";
      options = [ "ro" "resolve-symlinks" "x-gvfs-hide" ];
    };
    aggregatedIcons = pkgs.buildEnv {
      name = "system-icons";
      paths = with pkgs; [
        #libsForQt5.breeze-qt5  # for plasma
        gnome.gnome-themes-extra
      ];
      pathsToLink = [ "/share/icons" ];
    };
    aggregatedFonts = pkgs.buildEnv {
      name = "system-fonts";
      paths = config.fonts.packages;
      pathsToLink = [ "/share/fonts" ];
    };
  in {
    "/usr/share/icons" = mkRoSymBind "${aggregatedIcons}/share/icons";
    "/usr/local/share/fonts" = mkRoSymBind "${aggregatedFonts}/share/fonts";
  };

  fonts = {
    fontDir.enable = true;
    packages = with pkgs; [
      noto-fonts
      noto-fonts-emoji
      noto-fonts-cjk
    ];
  };


Noto Color Emoji doesn't render on Firefox

Enable useEmbeddedBitmaps in your NixOs configuration.

fonts.fontconfig.useEmbeddedBitmaps = true;