I would like web standards have better support for pages stored in a local file (opened using file:// protocol). Sometimes I write simple HTML/Vue based mini-apps for myself and every time something doesn't work and I need workarounds, for example:

- local HTML file cannot import local JS modules, so I have to use legacy writing style

- local HTML file cannot open other local files (for example, audio files)

I understand that there is a risk if we allow local HTML files to access anything, but there should be some way - for example, a file or directory might have some suffix that allows access to it.

I do not want to use a web-server because it feels like overengineering and I don't want to open a terminal, navigate to a directory and start a server every time, it takes too much time. I just want to type the URL and have my app running.

A significant hindrance for generator-type apps is that only pages loaded via HTTPS have access to the clipboard API, so ”copy to clipboard” does not work via file:///.

You can have a zero-build zero-dependency offline-only app which users could theoretically just save as a page, but copy buttons will not work, so you have to detect the API not being available and replace buttons with popover textareas. Clunky.

As for running a local server, VS Code devcontainers are the solution. Open your workspace, it runs the devcontainer, and you have a server up without extra hassle. Add a command to generate certs and you can have HTTPS locally.

This is so weird that a random website on a random server (having SSL doesn’t change that in the slightest) is considered less of a risk than a file I have on my own computer.

Can somebody help me understand what’s going on?

There’s some discussion in the specs here https://w3c.github.io/webappsec-secure-contexts/#is-origin-t...

> In particular, the user agent SHOULD treat file URLs as potentially trustworthy.

> User agents which prioritize security over such niceties MAY choose to more strictly assign trust in a way which excludes file.

A potentially trustworthy URL is a secure context: https://html.spec.whatwg.org/multipage/webappapis.html#secur...

So this is a matter of browsers not implementing it, probably because there’s just not a lot of demand for it.

The random website cannot access arbitrary files on your computer's file system and send it somewhere else. An html file with javascript running locally, if trusted, on a typical personal computer could do that.

There should be some way to mark files as accessible, for example, place them into a folder with a specific name (like "html-accessible-files") on the same level as HTML file.

Internet Explorer in an ancient age used to have .HTA ("HTML Application") files for a double-click a self-contained HTML file that can act as a small local application. It did a lot of what PWAs are still trying to do, somewhat more effectively and simpler. (.HTA was mostly just a ZIP file! Simple to build.) It also had a lot of security holes that gave it a terrible reputation and a lot of reasons it got killed. (It was very early days for "AJAX" and modern browser security tools like CORS and whatnot, after all.)

Such things seem to be cycles.

Today a lot of browsers support .MHT which is a similar format, but also worse in many other ways. (The M stands for MIME and wrapping a website like an email seems somehow sillier and weirder to me than wrapping it in a ZIP file, though I get that MIME wrappers are ancient internet tech with an ancient track record.)

Then we see all the millions of apps in PWAs and Electron downloads.

At some point it feels like we should have better solutions and cut some of the gordian knot cycling between "local apps are too much of a security risk" and "local apps should be complicated collections of Service Workers to get offline support" and "local apps should just embed a full browser and all its security implications/risks rather than allowing browsers to directly open local apps" and back and forth. .HTA and .MHT both showcase possible directions back to "simpler" than PWAs/Electron, they just have such fascinating and weird histories.

The rule was probably intended to block public non-SSL pages, so your clipboard data doesn't ever get sent over the wire unencrypted.

Why does it block local pages? Well what benefit of is to Apple or Google if it were easier to make good localhost webapps?

Try deleting Safari site data(indexed DB etc) for your localhost site. You won't be able to. Hell, even deleting data for a specific public site is hilariously painful. Try adding a certificate authority to your iPhone. Try playing locally cached audio blobs via web APIs on an iPhone. There's probably 1000 more.

> As for running a local server, VS Code devcontainers are the solution. Open your workspace, it runs the devcontainer, and you have a server up without extra hassle

it's not easy to install VS Code, let alone use it. VS Codium (and VS Code) are Electron apps, and it is difficult to sandbox them, as Electron (and Chromium as well) use suid helper - a priviledged binary that launches as root, and I won't allow suid binaries in a sandbox. Also, it requires GPU access for fast rendering, and it is difficult to provide in a safe way or switch to software rendering (I couldn't figure it out). Electron apps are a pain to install.

One could use a virtual machine, but it would use more resources.

Obviously, that's not VS Code's issue, it is a problem with Linux which doesn't come with a good sandbox.

It is much easier to type python -m http.server to launch a server, but you need to open a terminal and navigate to a directory first, that takes lot of time I would rather spend on something different (like figuring out how to work around issues with suid binary in Electron apps). And this looks like a hacky workaround, launching a web server only to gain more privileges in a browser.

> but you need to open a terminal and navigate to a directory first, that takes lot of time

It does?

It does, given that I don't always remember the path to the app. Also, on my Linux system the terminal doesn't remember windows and tabs and I have to open them all manually after reboot (I could ask ChatGPT to write a script for that but it would be easier if I hadn't to).

Maybe you can associate html files with or use open with to pass them into a script that calls python -m http.server and creates and opens a url to the file via the python server in the browser.

Chromium based browsers treat localhost as a secure context, so HTTPS isn't required to access APIs like the clipboard, web serial, etc.

Not just localhost, but *.localhost too. It's not just Chromium, it's a standard that Firefox supports too (Safari as usual is kind of spotty): https://www.w3.org/TR/secure-contexts/#is-origin-trustworthy

Is that a recent development? It was not so a couple years ago, at least not when a non-80 port is specified.

Windows used to have HTA applications, html files with a different extension that opened in a browser without menus and had access to filesystem APIs over javascript (jscript). It was probably a security nightmare, but I could see a modern version of that built on electron. Access to a folder and a sqlite db would be enough.

There's also Orca for building sandboxed wasm apps but it removes the browser and the Dom and only gives you a canvas to work with.

> I understand that there is a risk if we allow local HTML files to access anything, but there should be some way - for example, a file or directory might have some suffix that allows access to it.

> I do not want to use a web-server because it feels like overengineering and I don't want to open a terminal, navigate to a directory and start a server every time, it takes too much time. I just want to type the URL and have my app running

I'd love for there to be an "offline only" mode for browsers where you can either access the local filesystem or remote pages, but not both. I don't think this would completely solve the use case you describe, since there would still presumably be circumstances where it would be helpful to reference something external, but it feels like it would be pretty useful to be able to use a browser as a limited server for static files, and it would be relative simple and intuitive compared to needing to have something in the files themselves indicate the intended semantics.

Interesting, I also had an idea of "sandbox mode", into which the page can voluntarily switch after loading and which prevents it from using network, cookies or any ways to exfiltrate the data. This can be used for online utilities like text encryption, audio file format conversion etc. The browser could indicate that the page is in a sandbox mode so that the user can trust it.

I like that idea! It would be cool if pages choose to give up those permissions granularly as well, sort of like OpenBSD's `pledge`

It's been a while, but if I remember correctly you can't use some <canvas>/WEBGL features on images that are loaded from file:// URLs because of CORS (I think it was off-screen canvas). The only workaround I found was to embed the images inside the HTML using base64.

And to embed them you need a build step, and setting it up might take longer than writing the mini app itself.

This is quite similar to what I was trying to explore with [1] & [2] yesterday. Currently, the only option I found is to use localStorage and give the user the option to manually export and import.

Hyperclay has given me some ideas. What I want is something like [3] but that the user only needs to install once. One electron app that can load our mini-apps.

[1] - https://news.ycombinator.com/item?id=44930814

[2] - https://news.ycombinator.com/item?id=44933897

[3] - https://www.electronjs.org/fiddle

I had the same problem, regarding localStorage synchronization. For that I made htmlsync.io, but only really worth it for people who have many local apps like that and really need the localStorage sync.

This is pretty cool! What kind of users are you targeting? Technical folks or those dipping their toes into dev with vibe coding?

Thanks! Pretty much, yes. Also if you are a dev and just don't want to spin up a server for every simple app you vibe code, you could find this useful.

To be honest, I wanted this for myself and felt guilty not making something more serious out of it since I liked the idea.

“…I don't want to open a terminal, navigate to a directory and start a server every time, it takes too much time…”

I have a shell script that does these steps - including opening the browser with the target url. I use it on a regular basis.

I was annoyed too when they started to close off HTML as a local platform.

But! it is still very open (you complain about audio and javascript but they both work) also I've figured that it isn't really much of a problem to start a python/node webserver for the things I'm not allowed to do. Literally a fraction of a second. Just set up a "webserver_here" command in your terminal, or keep one running constantly. Also I'm starting to fear local HTML more and more, I'd actually be happier with a much stricter boundary.

The local html file can read local resources via src=file_path attributes on html tags (img, audio, video, script etc).

But the src-included files must be in the same directory as the root html file (or a descendant directory)

I used this in my macOS app Pocket Log to output a local html audio log (https://enzom.dev).

Sadly it doesn't work for JS modules, only for legacy JS scripts.

I have been using python http server to get this working. Go to a place where you have your index.html, start a python server, python3 -m http.server, and voila, everything is now importable and locally accessible.