Search code examples
reactjsexpresshttpslocalhostnext.js

HTTPS on localhost using NextJS + Express


System Information

Goal

Serve the web application using SSL over HTTPS on localhost

What has been done

  1. Created basic NextJS application using Create Next App
  2. Generated a certificate and key using OpenSSL and moved it into the project directory
  3. Added the Express dependency
  4. Configured the app to use express inside server.js
  5. Changed script to use the server.js inside package.json scripts.

server.js

const express = require('express');
const next = require('next');
const dev = process.env.NODE_ENV !== 'production';
const app = next({ dev });
const handle = app.getRequestHandler();
const port = 3000;

const https = require('https');
const fs = require('fs');
const httpsOptions = {
  key: fs.readFileSync('./certificates/key.pem'),
  cert: fs.readFileSync('./certificates/cert.pem')
};

app
  .prepare()
  .then(() => {
    const server = express();

    server.get('*', (req, res) => {
      return handle(req, res);
    });

    server.listen(port, err => {
      if (err) throw err;
      console.log('> Ready on http://localhost: ' + port);
    });
  })
  .catch(ex => {
    console.error(ex.stack);
    process.exit(1);
  });

Extra Information

The app currently works when initialized using yarn dev. I have tried to serve the app over https using this answer but I was unable to figure out how to apply this to my current setup using NextJS.

I spent a lot of time researching the web how to apply this solution but have not yet found a way on how to make this work.

Any help is greatly appreciated.


Solution

  • You just need to use the createServer method of https module.

    const { createServer } = require('https');
    const { parse } = require('url');
    const { readFileSync } = require('fs');
    const next = require('next');
    
    const port = 3000;
    const dev = process.env.NODE_ENV !== 'production';
    const app = next({ dev });
    const handle = app.getRequestHandler();
    
    const httpsOptions = {
      key: readFileSync('./certificates/key.pem'),
      cert: readFileSync('./certificates/cert.pem')
    };
    
    app.prepare()
      .then(() => {
        createServer(httpsOptions, (req, res) => {
          const parsedUrl = parse(req.url, true);
          handle(req, res, parsedUrl);
        }).listen(port, err => {
          if (err) throw err;
          console.log(`> Ready on https://localhost:${port}`);
        })
      });