Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I force or redirect my next.js website to use https

I thought this would be a simple task, but I struggle to find a way to force my webpage to use https. The next.js webapp lives on the heroku servers and I've set up the SSL. Both https and http version works, but how to I force or redirect the website to use the https version. I've seen some solution using express, but nothing in my webapp are using express, is it required? Thanks.

like image 279
jan Avatar asked Jul 10 '26 08:07

jan


2 Answers

As of Nextjs v12, you can use middleware instead of a setting up a custom server.

Middleware is a better solution for the following reasons:

  • a custom server often requires additional dependencies (like express)
  • you give up some of the box features like automatic static optimization
  • Middleware can be scope to specific paths using the built in routing paradigm

Create a /pages/_middleware.ts (or .js) file with something similar to this:

import  { NextFetchEvent, NextRequest, NextResponse } from 'next/server'

type Environment = "production" | "development" | "other";
export function middleware(req: NextRequest, ev: NextFetchEvent) {
    const currentEnv = process.env.NODE_ENV as Environment;

    if (currentEnv === 'production' && 
        req.headers.get("x-forwarded-proto") !== "https") {
        return NextResponse.redirect(
           `https://${req.headers.get('host')}${req.nextUrl.pathname}`,
           301
        );
    } 
    return NextResponse.next();
}

I also created an npm package for this.

import sslRedirect from 'next-ssl-redirect-middleware';
export default sslRedirect({});
like image 101
NSjonas Avatar answered Jul 13 '26 16:07

NSjonas


There is a solution with an NPM library called heroku-ssl-redirect.

First off, install the library using npm i heroku-ssl-redirect.

Then, create a new server.js file with the following script.

const next = require('next');
const express = require('express');
const sslRedirect = require('heroku-ssl-redirect').default; // to make it work with 'require' keyword.

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

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

  // Express's middleware to automatically redirect to 'https'.
  server.use(sslRedirect());

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

  server.listen(port, err => {
    if (err) throw err;

    console.log(`Server starts on ${PORT}.`);
  });
});

Then, change the start script to be like this:

"scripts": {
  "dev": "next",
  "build": "next build",
  "start": "node server.js"
}

It should work.

Note that you could replace Express with the createServer method from native Node.js's http module. But I do this with Express to simplify the syntax.

Further reading: How to setup a custom server in Next.js.

like image 37
Nicholas Avatar answered Jul 13 '26 15:07

Nicholas



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!