Configuring localhost HTTPS for your Next.js App
Problem Statement
Next.js is a fantastic Server Side Rendering implementation of react. You can be wickedly efficient when building applications on Next.js But what if my local development environment requires ssl for authentiation or sign into my identity provider? How would I configure applications built on the Next.js framework that require https over local host?
As apps mature and add functionality such as authentication or integrations with other products, engineers will inevitable need to run code locally using https. While configuring https for localhost development is OS dependent due to the inherent nature of certificate management, this post will focus on configuring a Next.js App built using the create-next-app on Windows.
In order to run Next.js 3 over SSL we will need to
- Generate and configure an SSL certificate
- Install the certificate to a local Certificate Authority (CA), and
- Configure the Next.js dev sever to use our use our generated certificate.
Taken from the perspective of a Next.js app created using the create-next-app, we will tell Next.js to use a specific cert that we generated locally, and that cert will tell the browser to look to the local machine as the Certificate Authority for cert verification.
You can find all of the code for this project on my GitHub at https://github.com/BrianMikinski/nextjsssl
Plan of Action
- Clone nextjsssl Next.js Starter Project from my GitHub
- Install Chocolatey
- Install OpenSSL
- OpenSSL Certificate Creation
- Certificate Installation
- Update npm run-script
Clone nextjsssl Starter Project from GitHub
Rather than start from scratch, I already have an Next.js project configured to fast track building your local https cert and configure npm to start the Next.js development server in ssl mode. Clone this project from GitHub using
1
git clone https://github.com/BrianMikinski/nextjsssl.git
Now, let’s get started building our cert and configuring our Next.js app!
Install Chocolatey
Prior to creating an SSL cert to be installed in your local Certificate Authority, we need to first install OpenSSL.
When running on Windows, you can install OpenSSL using a fantastic package manager for Windows called Chocolatey. Go and grab the following PowerShell script that can be found at Installing Chocolatey and run them under an admin PowerShell window. After installing Chocolatey as a package manager, we’re now ready to install OpenSSL (Note: you definitely will need to close your PowerShell window and may even need to restart your computer after installing Chocolatey to get the $PATH environment variable to properly pick up)
1
Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))
Install OpenSSL
With Chocolatey installed, we’re ready to install OpenSSL (using Chocolatey) which will allow us to generate certificates and keys for the Next.js CLI to us.
1
choco install openssl
To test that open ssl was properly installed, run the following command
1
openssl version
If you recieved output stating the version of OpenSSL that you are running, you should be good to go.
OpenSSL Certificate Creation
With OpenSSL installed the next step is to build a certificate that we will ultimately instal locally to the correct certificate authority. To generate the local cert, navigate to the Next.jsssl repo folder that was cloned from github and run the generateSslCert.ps1 PowerShell script. This script will call OpenSSL passing in cert definition defined in ./ssl/certdef.cnf and place the certificate along with a key in the ./ssl folder of the nextjsssl starter project.
certdef.cnf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
[req]
default_bits = 2048
prompt = no
default_md = sha256
x509_extensions = v3_req
distinguished_name = dn
[dn]
C = US
ST = TX
L = HTX
O = IT
OU = IT Department
emailAddress = webmaster@ustxhtx.com
CN = localhost
[v3_req]
subjectAltName = @alt_names
[alt_names]
DNS.1 = *.localhost
DNS.2 = localhost
Generate SSL Cert PowerShell Script
1
./generateSslCert.ps1
Note: If you haven’t yet downloaded the nextjsssl repo or simply do not wish to clone the repo, the openssl command to create your localhost cert can be found below…
generateSslCert.ps1
1
2
3
4
5
6
7
8
9
10
11
# generate an ssl cert a .cnf cert definition found in the
openssl req `
-newkey rsa:2048 `
-x509 `
-nodes `
-keyout ./ssl/server.key ` # replace with correct file path
-new `
-out ./ssl/server.crt ` # replace with correct file path
-config ./ssl/certdef.cnf ` # replace with correct file path
-sha256 `
-days 365
With the certificate and key created, we can now move on to installing the cert and updating our packages.json script
Certificate Installation
To install the certificate on Windows, navigate to the nextjsssl/ssl/ folder and double click on the certificate. This will open up the Certificate Import Wizard. On the Certificate Import Wizard, click through the wizard to place the certificate in the following location
Install Certificate > Current User > Place all Certificates in the following store > Browse > Trusted Root Certification Authorities > Ok
1. Click Install Certificate

2. Select Current User

3. Select Place all Certificates in the following store, Browse

4. Select Trusted Root Certification Authorities

5. Select Finish

Create a Custom Server for Next.js
Everything is now in place to start running Next.js with SSL enabled on localhost. To bring localhost ssl to completion, we need to make a couple of changes to how we are hosting our Nextjs application. Rather than utilize the out of the box Next.js server, we will configure our own custom server for local testing. Per the documentation, it is worth noting that there are some potential side affect to hosting your app with a custom server. First and forement, you will have to properly route any api calls in your custom server. Second, if you are deploying on Vercel, you will not be able to bring your custom server with you. With those bases covered, let’s look at the new custom server that will enable all this goodness.
To create our custom server for Next.js, we’re going to create a new file in the root of the solution called server.js. If you are looking at other custom server setups online, you will likely find very similar setups. At first glance the files may look almost identical but I want to point out a couple of differences that make the Next.js custom server a reality
require('https')
notrequire(http)
- If you forget to change your server.js to include the https package, the server will not include your ssl options and thus https will fail in the browser.
sslOptions
- As you configure your key and cert parameters in the ssl options, be sure they point to the correct path. Incorrect paths will cause your localhost app to fail to load in the browser
server.js scripts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
const next = require('next')
// note the "https" not "http" required module. You will get an error if trying to connect with https
const https = require('https')
const { parse } = require("url");
const fs = require("fs");
const hostname = 'localhost'
const port = 3001
const dev = process.env.NODE_ENV !== 'production'
const app = next({dev, hostname, port });
const sslOptions = {
key: fs.readFileSync("./ssl/server.key"),
cert: fs.readFileSync("./ssl/server.crt")
}
const handle = app.getRequestHandler()
app.prepare().then(() => {
const server = https.createServer(sslOptions, (req, res) => {
// custom api middleware
if (req.url.startsWith('/api')) {
return handle(req, res);
} else {
// Handle Next.js routes
return handle(req, res);
}
})
server.listen(port, (err) => {
if (err) throw err
console.log('> Ready on https://localhost:' + port);
})
})
Starting Next.js Custom Server with npm
In addition to configuring our Custom Server, we will need to make a slight change in how we start our Next.js application in the packages.json. We will be changing the npm start command from next start to node server.js. See the following packages.json for details
packages.json
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
{
"name": "nextjsssl",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "node server.js", // previously "next start"
"lint": "next lint"
},
"dependencies": {
"@types/node": "18.15.13",
"@types/react": "18.0.37",
"@types/react-dom": "18.0.11",
"next": "13.3.0",
"react": "18.2.0",
"react-dom": "18.2.0",
"typescript": "5.0.4"
}
}
Finally, with these updates we’re ready to run the app. Start up the app by running
1
npm run serve
If all goes well you should see npm start the compilation of your app and spin up the custom server for Next.js!
we Feel free to leave a comment below, thanks for learning along with me and happy coding!
Resources
Brian Mikinski nextjsssl GitHub Next.js Advanced Features - Custom Server