Redirect Next.js from http to https on Heroku

Viewed 711

I have found many solutions to this question, but they all require either breaking SSR using a custom server, or breaking the API routes in Next.js. I need to redirect to https and still have SSR and API routes working.

I've tried using several variations of node and express custom servers and the nginx buildpack, none of which solved the criteria listed. The code below is the closest I've got to getting this to work. It works on the first load but then breaks on subsequent loads from non-secure http. This may also still break SSR.

const { createServer } = require('http');
const { parse } = require('url');
const next = require('next');

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

app.prepare().then(() => {
  createServer((req, res) => {
    res.setHeader(
      'strict-transport-security',
      'max-age=31536000; includeSubDomains; preload'
    );

    if (req.headers['x-forwarded-proto'] === 'http') {
      res.writeHead(301, { Location: `https://${req.headers.host}${req.url}` });
    }

    const parsedUrl = parse(req.url, true);
    handle(req, res, parsedUrl);

  }).listen(process.env.PORT, (err) => {
    if (err) throw err;
    console.log('> NextJS Server running...');
  });
});
1 Answers

You can achieve this thing by Express integration. Next.js server can not help you in this thing completely at this point.

Express integration

const express = require('express')
const next = require('next')

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

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

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

  server.listen(port, (err) => {
    if (err) throw err
    console.log(`> Ready on http://localhost:${port}`)
  })
})

Now using the heroku-ssl-redirect you can get the desired result.

Install heroku-ssl-redirect

npm install heroku-ssl-redirect

Now go into your server.js file and enter the following at the beginning:

const sslRedirect = require('heroku-ssl-redirect');

And then add this line below where express is implemented, but before the code that calls the GET route for the landing page :

app.use(sslRedirect());

It’s very important that you get the order right. Hope this solves your problem!

Related