Using Next.js dev server with HTTPS

3 min read

At some point in lifecycle of your project you might need to run your Next.js (or any other) development server with HTTPS. Currently, there’s no way to do it out of the box in the framework itself, but there’s a simple way to work around it. We need self-signed certificates and a local SSL proxy.

The setup

Certificates

First, we need to create certificates. We’ll use mkcert for that. Follow the instructions in the link to install it on your machine. Once installed, we’re ready to create certificates for localhost.

# First, create a local certificate authority
mkcert --install

# Then, create a certificate for localhost
mkcert localhost

This will create two files: localhost.pem and localhost-key.pem. We’ll use them in a moment. A good practice is to add them to .gitignore file, as we don’t want secrets to leak to the repository. If you bootstrapped Next.js using create-next-app, it’s conveniently already there.

You could also create a certificate for a custom domain. A common pattern for me is to run my projects locally with HTTPS and adding local. suffix to the domain. For example, if I’m working on example.com, I’ll run it locally as local.example.com. This type of setup requires further configuration.

# Crate a certificate for local.example.com
mkcert local.example.com

This will create two files: local.example.com.pem and local.example.com-key.pem.

We also need to add this domain to our local hosts file. On Linux and macOS systems, it’s located at /etc/hosts.

# /etc/hosts
127.0.0.1 local.example.com

Proxy

Now that we have certificates, we could set up proxy server, that will handle HTTPS requests and forward them to our Next.js dev server. For this purpose, we’ll use local-ssl-proxy. It’s a simple proxy using self-signed certificates, and is intended for local development only. Exactly what we need!

npm i --save-dev local-ssl-proxy

Now, let’s add a convenience npm script to package.json. We’ll use it to start our proxy server. This example assumes we’re using default port of Next.js dev server, which is 3000 and that we’re using custom domain local.example.com.

{
  "scripts": {
    "dev": "next dev",
    "proxy": "local-ssl-proxy --source 3001 --target 3000 --key local.example.com-key.pem --cert local.example.com.pem"
  }
}

Now we could run our dev server with npm run dev and start proxy server with npm run proxy. You should now be able to access your Next.js dev server at https://local.example.com:3001.

One more thing

It’s a bit inconvenient to run two commands every time we want to start our dev server. Let’s install concurrently to take care of it for us.

npm i --save-dev concurrently

Now we could add convenience script to package.json to start both servers at once.

{
  "scripts": {
    "dev:ssl": "concurrently npm:dev npm:proxy",
    "dev": "next dev",
    "proxy": "local-ssl-proxy --source 3001 --target 3000 --key local.example.com-key.pem --cert local.example.com.pem"
  }
}

Conclusion

This simple setup gives us a lot of flexibility. It’s extremely convenient for local development and testing. You could for example, work on multiple projects locally, have them share the same domain, certificates or even cookies if needed. I hope you’ll find it useful!