v1.26.1

gildas-lormeau/SingleFilev1.26.1Sep 20, 2026by gildas-lormeau

Upgrading?

AI Summary

This release focuses on optimizing saved page sizes by aggressively removing unused fonts and rules, while fixing critical bugs that previously caused necessary content to be dropped. It also improves the stability of the self-extracting archive format and resolves preservation issues for popovers, dialogs, and duplicated stylesheets.

Key Highlights

  • Saved pages are significantly smaller due to advanced font optimization and removal of unused rules/images.
  • Fixed font dropping issues to ensure necessary fonts (e.g., used by pseudo-elements) are preserved.
  • Self-extracting archives now deduplicate identical resources and produce deterministic output.
  • Fixed content loss in popovers, dialogs, and duplicated style elements.
  • Progress reporting now correctly includes resources inside nested frames.

New Features

  • Font optimization to reduce payload size by merging weights and removing unused subsets.
  • Deduplication of identical font and image resources in self-extracting archives.
  • Deterministic ordering of entries and resources in the archive.
  • Serialization of adopted stylesheet text for shadow roots.
  • Improved Russian language translation.

Full Release Notes

### Changes

- single-file-core is updated from 1.6.5 to 1.6.7, see https://github.com/gildas-lormeau/single-file-core/releases/tag/v1.6.6 and https://github.com/gildas-lormeau/single-file-core/releases/tag/v1.6.7
- Saved pages are smaller: font faces the browser can never select are no longer kept (a face whose declared weight is not the one the page draws, a `unicode-range` subset entirely covered by a later subset of the same family, a subset whose range meets the page only on a tab or a newline, a subset whose characters are never drawn in that family), rules whose pseudo-element or state selector matches nothing are removed again together with the images they reference, and two `@font-face` rules naming the same font at two weights are merged into one rule with a weight range so the payload is embedded once
- In a self-extracting archive, two fonts or two images whose bytes are identical are stored once, a stylesheet emptied by the unused-rules removal is no longer written as an empty file with a `<link>` pointing at it, entries are written in the order the resources were registered, frames are numbered in document order and imported stylesheets in document order, so two saves of an unchanged page produce the same archive
- The text of an adopted stylesheet is serialized once and reused for every shadow root that adopts it
- Improved Russian translation (#1996 by @solokot)
- The CI workflows run on Ubuntu 26.04

### Fixes

- Faces the page needs are no longer dropped: fonts used only by `html::before` or `html::after`, fonts declared on `::marker`, `::first-line`, `::placeholder` or `::file-selector-button`, and two rules naming the same font that differ only in `size-adjust` or another metric override. Fonts used only by elements inside `<head>` are no longer recorded as used
- A `<style>` element repeated verbatim in a page is now minified at the position of its last copy; a rule of the same specificity placed between two copies used to win in the saved page while the browser draws the last copy
- A popover opened by a `popovertarget` button and a dialog opened by a `commandfor` button lost their content in the saved page; their content is now kept, and so are CSS rules matching `[open]`
- An iframe with `visibility: hidden` is treated as hidden whatever its size
- A video whose frame could not be captured used to get an empty poster, a broken image; the empty snapshot is dropped and a poster is retried later
- A duplicated `<style>` carrying an `@import` left `@import url(data:,)` in the archive with the imported stylesheet nowhere in the file
- The progress reported while a page is saved left out every resource inside a frame, so the maximum was reached early
- In an archive embedded in a PNG, a chunk length that spells the wrapper's closing pattern is padded by one byte, where the wrapper used to close early and leak bytes as text
- The self-extracting page refuses to extract when it finds more than one candidate holding the archive

Related Repositories