← Back to context

Comment by maxloh

1 day ago

I find SingleFile [0] to be a much more robust version of this.

It strips out all the JavaScript too, but also packs everything into a single HTML file that is easy to transfer. Binary assets (like web fonts and images) are packed as base64 strings.

They also offer a CLI powered by Puppeteer. [1]

[0]: https://github.com/gildas-lormeau/singlefile

[1]: https://github.com/gildas-lormeau/single-file-cli

It seems this repo only saves one web page?

What I'm implementing here is mirroring a whole website, with all its subpages, so you can browse it all offline. For example, all essays from paulgraham.com.

Love love love SingleFile too. The FF extension works pretty well for a clean save.

That said, Kage looks promising if OP can combine SingleFile reproduction quality with the HTTPTrack spidering approach. SPA's are kinda tricky with archiving and do wonder how well Kage would handle that

  • I've seen the option in IE- .mhtml.

    For some reason it displays in IE better but I don't recall seeing this option in chrome of Firefox recently..

And thanks for the link. Let me implement this single HTML feature, it looks nice to have!

  • Yeah. An idea on top of that is to bundle an entire website into a single HTML page, with vendored JavaScript to enable client-side routing (all of the original pages' JS is still stripped out).

    That way, the page is self-contained as it is, but requires no bundled binary code to serve the site. It is actually safer security-wise.

    The vendored script can be as simple as this:

      const site = {
        "path-1": "<!DOCTYPE html><html> ... </html>",
        "path-2": "<!DOCTYPE html><html> ... </html>",
        // More paths
      }
    
      function attachListeners() {
        for (const [path, html] of Object.entries(site)) {
          document.querySelector(`a[href=${path}]`).onclick = () => {
            document.documentElement.outerHTML = html
            attachListeners()
          }
        }
      }
    
      document.addEventListeners("DOMContentLoaded", attachListeners)

What's the difference with, any webbrowser on a computer, File -> Save as ?

  • That's for a single page, this handles the whole site. Also the browser Save As options often work poorly.

  • Save As works fine for simple websites with static content.

    Let's say you have a site that fetches content from a database. If you Save As, then at best you'll get a local copy of an HTML page with JS that loads the content from the same remote database. It might not work (since the local copy has a different origin), or if it does, it requires you to be online, which defeats half of the purpose.

    What this project, and SingleFile, both do is save a snapshot of what the rendered page actually looks like at that moment in time. The scripts are stripped out so it runs locally and has no external dependencies.

This is what I first thought and it's a very elegant solution, and not needlessly overcomplicated.