Local HTTPS: When plain localhost isn't enough

For most day-to-day development, http://localhost is perfectly fine. Browsers treat it as a special case: although it technically runs over HTTP, it enjoys secure context status. That means features like Service Workers, the Web Authentication API, Sensor APIs, and Payments all work as they would on a live HTTPS site.

But there are exceptions where a secure context isn't enough, or where you need to reproduce an issue that only appears under real HTTPS. In those situations, you need to switch your local server from HTTP to HTTPS.

Default to http://localhost

The reasoning is simple: keep your local environment as close to production as possible. If your production site runs on HTTPS, your local site should behave like an HTTPS site where it matters. Since browsers already grant http://localhost secure-context behavior, this is mostly automatic.

Note that everything said about localhost also applies to the loopback addresses 127.0.0.1 and [::1], including any port number you might append.

When you need real HTTPS locally

There are a handful of cases where plain http://localhost will not behave like an HTTPS site, or where HTTPS is a hard requirement:

  • Debugging mixed-content issues. If your bug only reproduces when a page contains HTTPS and HTTP resources together, http://localhost won't help you reproduce it. You need an actual HTTPS page.
  • Testing HTTP/2 or newer protocols. Insecure HTTP/2 is not supported in browsers at all—not even on localhost. If your work involves measuring loading performance or testing features over HTTP/2, you'll need a local HTTPS server.
  • Using third-party services that mandate HTTPS. Libraries and APIs that use OAuth or similar auth flows typically require HTTPS in their redirect URIs. http://localhost often won't satisfy those constraints.
  • Using a custom hostname. If you've edited your hosts file to map mysite.example to 127.0.0.1 and open that address in your browser, you lose the secure-context treatment. Chrome, Edge, Safari, and Firefox do not consider arbitrary local hostnames secure by default, even when they resolve to your local machine.
  • Other edge cases. The list isn't exhaustive. If something inexplicably fails on http://localhost, or a feature there behaves differently than your production HTTPS site, treat it as a signal to test with local HTTPS.

The common thread: when your local site needs to act like a real HTTPS site, make it one.

Working with custom hostnames

If you do go the custom hostname route and skip http://localhost, a few practices will save you trouble:

  • Avoid bare hostnames. A name like mysite could collide with a real top-level domain. The list of TLDs is long and growing—names like coffee, museum, and travel already exist, for example. Any bare name you pick might already be a TLD.
  • Use reserved names by default. If you don't own a real domain, reserve the test TLD for local work. Alternatively, leverage localhost itself as a TLD: Chrome and Edge treat http://<yourname>.localhost as a secure context out of the box, so a name like mysite.localhost gives you custom-hostname behavior without requiring HTTPS or hosts-file edits.

Next steps

Some browsers support several modern features only on secure contexts. If you want to dig into these topics, check out:

  • Secure contexts specification and the rationale for treating localhost as one.
  • Mixed-content rules and how they differ between HTTP and HTTPS pages.