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.
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:
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({});
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With