Mixed content occurs when a webpage served over HTTPS loads a resource over HTTP. Browsers block these mixed content resources to protect your security, but blocked resources can break your pages. These bugs often slip through to production because browsers specifically allow mixed content on http://localhost pages. Switching to HTTPS in local development will make our browser block mixed content and behave the same for the local and deployed version.
Getting HTTPS setup and working with an app in local development is tricky. There were two options: acquire a publicly-trusted certificate from a CA, or make your own self-signed certificate from the command line. Neither of these options are simple, that's why most developers skip HTTPS in their development environment. But lcl.host now makes this quick and easy.
lcl.host is a free developer tool from Anchor.dev to setup a local HTTPS development environment in minutes. It combines the best parts of both public CA certificates and self-signed certificates, and it's built for novice and expert web developers alike. Read more about how lcl.host works on the Anchor blog.
Now we will look at mixed content issues in practice with an example app which attempts to load a script asset over HTTP. Our browser will allow the script to load via http://localhost but will block the script over HTTPS, just as it does with deployed apps. Using HTTPS in local development let's us catch mixed content warnings and errors before we deploy and cause issues for users.
Mixed Content Example App
anchordotdev/mixed-content-example is a nodejs app that triggers a mixed content error when served over HTTPS. We'll start by setting up the app and running it with just HTTP, which won't trigger any errors at all.
Browse to http://localhost:3000/ and you'll see "INSECURE SCRIPT LOADED AND RUN!!!", demonstrating that the insecure script loaded without any errors.
This script will always be insecure because it's always served over HTTP, yet our browser allowed it through! Next let's setup and use lcl.host to serve the page over HTTPS and secure our page.
lcl.host
Setting up local HTTPS used to be a pain, but lcl.host makes it easy: install the CLI, run anchor lcl, and work through the guided steps:
For the example, we use the suggested values for all the prompts. Once you are done, restart the app, and you'll see it is now listening on both HTTP and HTTPS:
Now open the HTTPS version in your browser, and be sure to use the port number returned when you run the app, which may differ from what we depict here. Notice this time the "INSECURE" message doesn't appear, because your browser blocked the script for you.
If we look in the devtools console, we also can see there is now a "Mixed Content" error for the insecure simple-example.js script.
Working through this example helped us reproduce mixed content errors and catch them in our dev tools console. You can use lcl.host to catch mixed content bugs in all your web applications too.
Real World Apps
Using lcl.host with real development apps works the same as the example: run anchor lcl in the project directory and follow the guide. Check out the lcl.host docs to learn more about other issues that local HTTPS helps mitigate.