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...');
});
});